本篇文章為大家展示了如何在PHP中使用cookie實(shí)現(xiàn)跨域session共享,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。
成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站,成都做網(wǎng)站公司-成都創(chuàng)新互聯(lián)公司已向1000+企業(yè)提供了,網(wǎng)站設(shè)計(jì),網(wǎng)站制作,網(wǎng)絡(luò)營(yíng)銷(xiāo)等服務(wù)!設(shè)計(jì)與技術(shù)結(jié)合,多年網(wǎng)站推廣經(jīng)驗(yàn),合理的價(jià)格為您打造企業(yè)品質(zhì)網(wǎng)站。設(shè)置cookie無(wú)效
setcookie("sso", "e589hR6VnO8K1CNQZ4PSP/LWGBhRKE5VckawQwl1TdE8d4Q5E7tW", 900);
這個(gè)問(wèn)題很多剛?cè)腴T(mén)php的小伙們都會(huì)碰到。這個(gè)代碼的本意應(yīng)當(dāng)是想設(shè)置cookie sso的有效期為15分鐘,可是執(zhí)行這個(gè)代碼后發(fā)現(xiàn)沒(méi)有效果。為什么呢?因?yàn)榈谌齻€(gè)參數(shù)expire表示的是過(guò)期的時(shí)間節(jié)點(diǎn),而不是有效時(shí)間,所以如果希望設(shè)置cookie為15分鐘,正確的做法應(yīng)當(dāng)是獲取當(dāng)前的時(shí)間戳加上15分鐘。
setcookie這個(gè)函數(shù)還有path、domain參數(shù)都比較常用,強(qiáng)烈建議剛學(xué)php的小伙們多翻閱手冊(cè)。php手冊(cè)地址: http://php.net/manual/zh/index.php
獲取cookie值獲取不到
先看這樣一段代碼
setcookie("sso", "e589hR6VnO8K1CNQZ4PSP/LWGBhRKE5VckawQwl1TdE8d4Q5E7tW", time() + 900); var_dump($_COOKIE["sso"]);
要解決這個(gè)問(wèn)題,要先了解一下setcookie后發(fā)生了什么?因?yàn)閏ookie是保存在客戶(hù)端的,php是服務(wù)端語(yǔ)言,實(shí)際上setcookie之后只是在返回的http頭增加一個(gè)cookie的頭信息,告訴客戶(hù)端需要設(shè)置一個(gè)醬紫的cookie,如下圖:
php中setcookie返回的http頭
而$_COOKIE這個(gè)數(shù)組里面保存客戶(hù)端傳遞上來(lái)的cookie。自然第一次刷新的時(shí)候因?yàn)榭蛻?hù)端沒(méi)有相應(yīng)的cookie值,所以$_COOKIE是沒(méi)有sso的信息的。第一次請(qǐng)求過(guò)后,因?yàn)榉?wù)器設(shè)置了cookie sso,所以第一次請(qǐng)求過(guò)來(lái)客戶(hù)端就有了cookie sso的信息,所以第二次請(qǐng)求的時(shí)候就會(huì)帶上sso的信息,服務(wù)端就能通過(guò)$_COOKIE取到值了。
cookie跨域問(wèn)題
這個(gè)可以說(shuō)是cookie中一個(gè)比較熱門(mén)的問(wèn)題,面試的時(shí)候一般很愛(ài)聊這方面的問(wèn)題。
跨域的業(yè)務(wù)需求大概是醬紫:用戶(hù)在a.com進(jìn)行了登錄,希望在b.com也同步進(jìn)行了登錄。如果是同一個(gè)主域比較簡(jiǎn)單,可以通過(guò)setcookie中的domain參數(shù)進(jìn)行設(shè)定:例如有x.a.com和xx.a.com,可以通過(guò)設(shè)置domain為a.com,從而a.com的所有二級(jí)域名都可以共享這一個(gè)cookie?;诎踩矫娴脑?,在a.com下面設(shè)置domain為b.com是無(wú)效的。
那么是否真的沒(méi)有辦法可以實(shí)現(xiàn)這個(gè)了呢?這個(gè)還是有一些奇巧淫技的,這里介紹一種使用內(nèi)框iframe的方法。
具體思路:在a.com下設(shè)置cookie后,嵌入一個(gè)iframe框鏈接b.com的頁(yè)面,b.com設(shè)置好頁(yè)面cookie后,再嵌入一個(gè)a.com的頁(yè)面,然后通過(guò)parent.parent就可以調(diào)用最外層的a.com的js方法,從而進(jìn)行跳轉(zhuǎn)或者一些其它的操作。具體代碼示例如下:
假設(shè)a.com有頁(yè)面:login.php和callback.php,b.com有頁(yè)面synclogin.php
a.com的login.php代碼:
login success...
b.com的synclogin.php頁(yè)面
a.com的callback.php頁(yè)面
代碼看起來(lái)也不難,值得一提的是這里嵌入了兩個(gè)iframe,因?yàn)槿绻挥靡粋€(gè)iframe的話(huà),即在b.com的synclogin.php內(nèi)直接調(diào)用父窗體的jumpTo方法,在有些瀏覽器下會(huì)提示沒(méi)有權(quán)限的錯(cuò)誤:
Error: Permission denied to access property
這里只是演示了cookie跨域同步的思路,具體細(xì)節(jié)還有很多可以改進(jìn)的地方,比如iframe鏈接的頁(yè)面可以考慮改成靜態(tài)的頁(yè)面,這樣效率會(huì)比php動(dòng)態(tài)頁(yè)面快很多,還有像參數(shù)校驗(yàn)、多個(gè)主域(比如還有c.om)同時(shí)登錄等等,這里就不再累述。
cookie的總結(jié)到這里就結(jié)束,如果你感覺(jué)有一些收獲,可以在頁(yè)面底部掃碼給我打賞喲,感謝O(∩_∩)O~
session
$_SESSION
沒(méi)有值
這個(gè)session使用和cookie有一點(diǎn)不太一樣,session使用前必須先調(diào)用session_start
方法。否則會(huì)收到一個(gè)undefined的錯(cuò)誤:
Notice: Undefined variable: _SESSION
session存儲(chǔ)在哪
session存儲(chǔ)在服務(wù)端,但是session究竟是存儲(chǔ)在哪呢?php.ini中關(guān)于session有一個(gè)save_path的選項(xiàng)可以設(shè)置存放的目錄,如果這個(gè)選項(xiàng)沒(méi)有設(shè)置值,那么就存儲(chǔ)在系統(tǒng)默認(rèn)的tmp目錄下。默認(rèn)的tmp目錄可以通過(guò)sys_get_temp_dir方法取到。
例如在mac下面,php的session一般會(huì)存儲(chǔ)在/var/tmp目錄下。
session_start(); echo session_id();//本例輸出ipkl446enhae25uq92c28u4lo3 $_SESSION['name'] = "tony”; $_SESSION['users'] = array("tony", "andy");
通過(guò)session_id方法可以取到當(dāng)前的session編號(hào),通過(guò)這個(gè)編號(hào)可查看一下該session文件。
$ sudo more /var/tmp/sess_ipkl446enhae25uq92c28u4lo3 name|s:4:"tony";users|a:2:{i:0;s:4:"tony";i:1;s:4:"andy";}
可以清楚的看到session存儲(chǔ)數(shù)據(jù)的結(jié)構(gòu),其中值是用序列化的方式進(jìn)行轉(zhuǎn)化存儲(chǔ)的。
session也用了cookie
session不是存儲(chǔ)在服務(wù)端嗎,怎么又和cookie扯上關(guān)系了?其實(shí)想想也簡(jiǎn)單,因?yàn)榭蛻?hù)端再請(qǐng)求的時(shí)候,服務(wù)端怎么樣才能知道該客戶(hù)端的session存儲(chǔ)在哪個(gè)文件呢?其實(shí)也是通過(guò)cookie PHPSESSID來(lái)進(jìn)行標(biāo)識(shí)。
php中session的cookie標(biāo)識(shí)
php在進(jìn)行session操作的時(shí)候會(huì)生成一個(gè)session id,而后把這個(gè)值以cookie的形式保存在客戶(hù)端,就是圖示中的PHPSESSID了。客戶(hù)端在下次請(qǐng)求的時(shí)候就會(huì)帶上這個(gè)PHPSESSID,服務(wù)端就能知道當(dāng)前客戶(hù)端對(duì)應(yīng)的session文件了
session超時(shí)設(shè)置
cookie超時(shí)設(shè)置比較簡(jiǎn)單,一個(gè)參數(shù)就搞定了。session這邊有點(diǎn)小麻煩,既不能單獨(dú)設(shè)置cookie PHPSESSID的超時(shí)時(shí)間,也不能單獨(dú)設(shè)置服務(wù)端文件的超時(shí)時(shí)間。具體的可以參考鳥(niǎo)哥這篇文章:如何設(shè)置一個(gè)嚴(yán)格30分鐘過(guò)期的Session,真的非常嚴(yán)謹(jǐn),贊一下。
session服務(wù)器共享
這個(gè)問(wèn)題和cookie的跨域類(lèi)似,面試的時(shí)候也很愛(ài)聊這個(gè)問(wèn)題。
以前在做服務(wù)器集群的時(shí)候會(huì)碰到這樣的一樣問(wèn)題,就是用戶(hù)一會(huì)訪問(wèn)是處于正常登錄狀態(tài),一會(huì)訪問(wèn)又沒(méi)有登錄了。這個(gè)問(wèn)題偶爾才會(huì)出現(xiàn)。跟蹤代碼下去才發(fā)現(xiàn)session沒(méi)有取到相應(yīng)的值,想想也是醉了:原來(lái)服務(wù)器session沒(méi)有設(shè)置共享,session存在在本地文件目錄,當(dāng)用戶(hù)訪問(wèn)另外一臺(tái)服務(wù)器的時(shí)候自然就取不到session了。
解決方法也不難,通過(guò)共享的存儲(chǔ)在進(jìn)行服務(wù)器之間的共享。這里使用redis的進(jìn)行session存儲(chǔ)。可以通過(guò)php.ini配置文件進(jìn)行調(diào)整,也可以在代碼中通過(guò)ini_set
進(jìn)行調(diào)整
ini_set("session.save_handler", "redis"); ini_set("session.save_path", "tcp://127.0.0.1:6379”);
如果需要使用redis進(jìn)行存儲(chǔ),需要session中的Registered save handlers支持redis
上述內(nèi)容就是如何在PHP中使用cookie實(shí)現(xiàn)跨域session共享,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。