成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

詳解Session

joy968 / 1626人閱讀

摘要:會在腳本執(zhí)行完畢或調(diào)用函數(shù)之后調(diào)用此回調(diào)函數(shù)。此回調(diào)函數(shù)操作成功返回,反之返回。在回調(diào)函數(shù)中,以傳入的作為,以的值作為中的值存入,并設(shè)置過期時間為秒方法以傳入的為從取出相應(yīng)的的值。

1 Session的基本概念和設(shè)置

Session存儲在服務(wù)端,本質(zhì)上和Cookie沒有區(qū)別,都是針對http協(xié)議的局限性而提出的一種保持客戶端和服務(wù)端間會話狀態(tài)的機制。Session經(jīng)常用來網(wǎng)站的上下文間實現(xiàn)頁面變量的傳遞,用戶身份認(rèn)證,程序狀態(tài)記錄等。常見的有配合cookie使用,實現(xiàn)保存用戶的登陸狀態(tài),或者記錄用戶的購物下單信息等。

在使用session之前必須先開啟session,可使用session_start()開啟session,同cookie一樣,在開始之前不能有任何輸出內(nèi)容,否則會出現(xiàn)如下警告:

Warning: session_start(): Cannot send session cookie - headers already sent

也可以修改php.ini中的session.auto_start = 0 為 session.auto_start = 1,設(shè)置自動開啟session支持,這樣就不必每次在使用session的時候都要加上session_start()了。

Session的設(shè)置非常簡單,可以直接使用$_SESSION[key]=value 的形式進行設(shè)置,其中key表示session的鍵,所有設(shè)置的session都存儲在全局?jǐn)?shù)組$_SESSION中。當(dāng)在代碼中設(shè)置了session時,在http請求的消息頭中會攜帶一個名為PHPSESSID的cookie,其值是一個32位16進制的字符串。每個客戶端向服務(wù)器請求時都會產(chǎn)生一個不同的值,如果清除掉瀏覽器的cookie,再次刷新頁面將會重新設(shè)置一個PHPSESSID的值。服務(wù)端接收到這個cookie,根據(jù)其值在服務(wù)器中找到對應(yīng)的session文件,從而實現(xiàn)保持與客戶端鏈接狀態(tài)的信息,其中session中存儲著序列化的session鍵值等信息。設(shè)置了session的http請求消息頭如下:

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8

Accept-Encoding:gzip, deflate, sdch, br

Accept-Language:zh-CN,zh;q=0.8

Cache-Control:max-age=0

Connection:keep-alive

Cookie:PHPSESSID=4680c9df2ce9ac4d1aa7f366bd92d83a

Host:localhost

Upgrade-Insecure-Requests:1

User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36

2 Session的工作原理和存儲機制

前文說到,session是通過一個名為PHPSESSID的cookie來和服務(wù)器取得聯(lián)系的,session通過sessionID(即PHPSESSID的值)來找到對應(yīng)服務(wù)器中session的文件名的。sessionID時在客戶端和服務(wù)端是通過 HTTP Requset 和 HTTP Response 傳來傳去的。sessionID按照一定的算法生成,保證其值的唯一性和隨機性。Cookie里存儲著session的sessionID和session的生存期,如果沒有設(shè)置session的生存期,則sessionID存儲在內(nèi)存中,關(guān)閉瀏覽器時session失效,重新請求頁面時回重新注冊一個sessionID。

默認(rèn)情況下,Session是存儲在服務(wù)器硬盤上的,在php.ini可通過session.save_path設(shè)置session文件的存儲路徑,默認(rèn)為服務(wù)器上/tmp目錄。此配置指令還有一個可選的 N 參數(shù)來決定會話文件分布的目錄深度。例如,設(shè)定為 "5;/tmp" 將使創(chuàng)建的會話文件和路徑類似于 /tmp/4/b/1/e/3/sess_4b1e384ad74619bd212e236e52a5a174If。要使用 N 參數(shù),必須在使用前先創(chuàng)建好這些目錄。在 ext/session 目錄下有個小的 shell 腳本名叫 mod_files.sh,windows 版本是 mod_files.bat 可以用來做這件事。此外注意如果使用了 N 參數(shù)并且大于 0,那么將不會執(zhí)行自動垃圾回收。文件儲存模塊默認(rèn)使用 mode 600 創(chuàng)建文件。通過 修改可選參數(shù) MODE 來改變這種默認(rèn)行為: N;MODE;/path ,其中 MODE 是 mode 的八進制表示。使用以上描述的可選目錄層級參數(shù) N 時請注意,對于絕大多數(shù)站點,大于1或者2的值會不太合適——因為這需要創(chuàng)建大量的目錄:例如,值設(shè)置為 3 需要在文件系統(tǒng)上創(chuàng)建 64^3 個目錄,將浪費很多空間和 inode。僅僅在絕對肯定站點足夠大時,才可以設(shè)置 N 大于2。一個session文件的內(nèi)容如下:

siteadmin_username|s:7:"special";siteadmin_truename|s:6:"特殊";siteadmin_usertype|i:1;

內(nèi)容的格式為:session名|值類型:長度:值; 。

3 使用Redis存儲Session

對于大訪問量的網(wǎng)站來說,會有許多的客戶端和服務(wù)端建立鏈接,那么將會生成許多的session文件,由于session文件是存儲在硬盤上的,每次服務(wù)器去讀取這些session文件都要經(jīng)過許多的I/O操作。PHP中可使用session_set_save_handle()函數(shù)自定義session保存函數(shù)(如打開,關(guān)閉,寫入,讀取等)。session_set_save_handle()語法如下:

bool session_set_save_handler ( callable $open , callable $close , callable $read , callable $write , callable $destroy , callable $gc [, callable $create_sid ] )

如果想使用 PHP 內(nèi)置的會話存儲機制之外的方式, 可以使用本函數(shù)。 例如,可以自定義會話存儲函數(shù)來將會話數(shù)據(jù)存儲到數(shù)據(jù)庫。該函數(shù)的參數(shù)解析如下。

open(string $savePath, string $sessionName):open 回調(diào)函數(shù)類似于類的構(gòu)造函數(shù), 在會話打開的時候會被調(diào)用。 這是自動開始會話或者通過調(diào)用 session_start() 手動開始會話 之后第一個被調(diào)用的回調(diào)函數(shù)。 此回調(diào)函數(shù)操作成功返回 TRUE,反之返回 FALSE。

close():close 回調(diào)函數(shù)類似于類的析構(gòu)函數(shù)。 在 write 回調(diào)函數(shù)調(diào)用之后調(diào)用。 當(dāng)調(diào)用 session_write_close() 函數(shù)之后,也會調(diào)用 close 回調(diào)函數(shù)。 此回調(diào)函數(shù)操作成功返回 TRUE,反之返回 FALSE。

read(string $sessionId):如果會話中有數(shù)據(jù),read 回調(diào)函數(shù)必須返回將會話數(shù)據(jù)編碼(序列化)后的字符串。 如果會話中沒有數(shù)據(jù),read 回調(diào)函數(shù)返回空字符串。在自動開始會話或者通過調(diào)用 session_start() 函數(shù)手動開始會話之后,PHP 內(nèi)部調(diào)用 read 回調(diào)函數(shù)來獲取會話數(shù)據(jù)。 在調(diào)用 read 之前,PHP 會調(diào)用 open 回調(diào)函數(shù)。read 回調(diào)返回的序列化之后的字符串格式必須與 write 回調(diào)函數(shù)保存數(shù)據(jù)時的格式完全一致。 PHP 會自動反序列化返回的字符串并填充 $_SESSION 超級全局變量。 雖然數(shù)據(jù)看起來和 serialize() 函數(shù)很相似, 但是需要提醒的是,它們是不同的。

write(string $sessionId, string $data):在會話保存數(shù)據(jù)時會調(diào)用 write 回調(diào)函數(shù)。 此回調(diào)函數(shù)接收當(dāng)前會話 ID 以及 $_SESSION 中數(shù)據(jù)序列化之后的字符串作為參數(shù)。 序列化會話數(shù)據(jù)的過程由 PHP 根據(jù) session.serialize_handler 設(shè)定值來完成。序列化后的數(shù)據(jù)將和會話 ID 關(guān)聯(lián)在一起進行保存。 當(dāng)調(diào)用 read 回調(diào)函數(shù)獲取數(shù)據(jù)時,所返回的數(shù)據(jù)必須要和 傳入 write 回調(diào)函數(shù)的數(shù)據(jù)完全保持一致。PHP 會在腳本執(zhí)行完畢或調(diào)用 session_write_close() 函數(shù)之后調(diào)用此回調(diào)函數(shù)。 注意,在調(diào)用完此回調(diào)函數(shù)之后,PHP 內(nèi)部會調(diào)用 close 回調(diào)函數(shù)。

PHP 會在輸出流寫入完畢并且關(guān)閉之后 才調(diào)用 write 回調(diào)函數(shù), 所以在 write 回調(diào)函數(shù)中的調(diào)試信息不會輸出到瀏覽器中。 如果需要在 write 回調(diào)函數(shù)中使用調(diào)試輸出, 建議將調(diào)試輸出寫入到文件。

destroy($sessionId):當(dāng)調(diào)用 session_destroy() 函數(shù), 或者調(diào)用 session_regenerate_id() 函數(shù)并且設(shè)置 destroy 參數(shù)為 TRUE 時, 會調(diào)用此回調(diào)函數(shù)。此回調(diào)函數(shù)操作成功返回 TRUE,反之返回 FALSE。

gc($lifetime):為了清理會話中的舊數(shù)據(jù),PHP 會不時的調(diào)用垃圾收集回調(diào)函數(shù)。 調(diào)用周期由 session.gc_probability 和 session.gc_divisor 參數(shù)控制。 傳入到此回調(diào)函數(shù)的 lifetime 參數(shù)由 session.gc_maxlifetime 設(shè)置。 此回調(diào)函數(shù)操作成功返回 TRUE,反之返回 FALSE。

create_sid():當(dāng)需要新的會話 ID 時被調(diào)用的回調(diào)函數(shù)。 回調(diào)函數(shù)被調(diào)用時無傳入?yún)?shù), 其返回值應(yīng)該是一個字符串格式的、有效的會話 ID。

一個關(guān)于使用Redis代替文件存儲session的例子如下:

首先編寫一個管理session的類sessionmanager,代碼如下:

redis = new Redis();

$this->redis->connect("10.116.19.14",6400);

$reval = session_set_save_handler(

array($this,"open"),

array($this,"close"),

array($this,"read"),

array($this,"write"),

array($this,"destroy"),

array($this,"gc")

);

session_start();

}

public function open($patn,$name){

return true;

}

public function close(){

return true;

}

public function read($id){

$value = $this->redis->get($id);

if($value) {

return $value;

} else {

return false;

}

}

public function write($id,$data){

if($this->redis->set($id,$data)) {

$this->redis->expire($id,60);

return true;

} else {

return false;

}

}

public function destroy($id) {

if($this->redis->delete($id)) {

return true;

}

return false;

}

public function gc($maxlifetime){

return true;

}

public function __destruct()

{

session_write_close();

// TODO: Implement __destruct() method.

}

}

?>

在該類的構(gòu)造函數(shù)中,使用session_set_save_handler()設(shè)置session的處理函數(shù),實例化該類時便完成了用指定函數(shù)接管系統(tǒng)處理session的工作。將以上代碼保存為sessionmanager.php文件。在write回調(diào)函數(shù)中,以傳入的sessionID作為key,以session的值作為redis中key的值存入redis,并設(shè)置過期時間為60秒;read方法以傳入的sessionID為key從redis取出相應(yīng)的session的值。destroy可根據(jù)傳入的sessionID刪除redis中的session。

我們編寫另外一個設(shè)置session的腳本,并引入sessionmanager.php文件,示例化sessionmanager類。代碼如下:

1,2,3,4,4);

?>

保存以上代碼為set.php,另外編寫一個可訪問session的腳本,代碼如下:


保存以上代碼為get.php文件。測試時,先訪問set.php,然后再訪問get.php,會在瀏覽器輸出以下結(jié)果:

array(4) { ["namehaha"]=> string(10) "lixiaolong" ["namehah"]=> string(10) "lixiaolong" ["namehaa"]=> string(10) "lixiaolong" ["namhaha"]=> array(5) { ["a"]=> int(1) [0]=> int(2) [1]=> int(3) [2]=> int(4) [3]=> int(4) } }

可見已經(jīng)成功的設(shè)置并獲得了session。查看redis中存儲的session信息,

redis 127.0.0.1:6400> get ruevh62hlm809d1p2lg2o0fbv7

“namehaha|s:10:"lixiaolong";namehah|s:10:"lixiaolong";namehaa|s:10:"lixiaolong";namhaha|a:5:{s:1:"a";i:1;i:0;i:2;i:1;i:3;i:2;i:4;i:3;i:4;}"

Redis中是以string的數(shù)據(jù)類型存儲session的,其key遍是sessionID,也是HTTP Request中的cookie名為PHPSESSID的值。session在redis和在文件中的存儲形式都是一樣的,只不過在redis對雙引號做了轉(zhuǎn)義。

本文節(jié)選自 《php7實踐指南》 陳小龍著

微信掃一掃,發(fā)現(xiàn)更多內(nèi)容

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/22538.html

相關(guān)文章

  • Cookie 和 session詳解

    摘要:協(xié)議是無狀態(tài)的,一旦數(shù)據(jù)交換完畢,客戶端與服務(wù)器端的連接就會關(guān)閉,再次交換建立新的連接,也就是說,服務(wù)器無法跟蹤會話。而和就是用與解決這種問題。值得一提的是是建立在的基礎(chǔ)上創(chuàng)建的。注意在的文件中,設(shè)置了的生命周期最長為分鐘。 在將cookie 和 session 之前需要先理解什么是會話會話: 用戶打開一個瀏覽器,點擊多個超鏈接,訪問多個web資源,然后關(guān)閉瀏覽器,整個過程稱為一個...

    wow_worktile 評論0 收藏0
  • Cookie和Session詳解

    摘要:例如要想在多個二級域名中共享,需要設(shè)置為頂級域名,這樣就可以在所有二級域名里面或者到這個的值了。頂級域名只能獲取到設(shè)置為頂級域名的,設(shè)置為其他子級域名的無法獲取。 Cookie和Session詳解 Cookie Cookie只存儲在客服端 Cookie是什么:Cookies是web服務(wù)器存放在用戶硬盤的一段文本,Cookies允許一個wen站點在用戶的機器存放一些文本的信息,并可以在以...

    Little_XM 評論0 收藏0
  • 詳解 Cookie 和 Session 關(guān)系和區(qū)別

    摘要:目前大多數(shù)的應(yīng)用都是用實現(xiàn)跟蹤的。的安全性一般,他人可通過分析存放在本地的并進行欺騙。在安全性第一的前提下,選擇更優(yōu)??紤]到減輕服務(wù)器性能方面,應(yīng)當(dāng)適時使用。因此,維持一個會話的核心就是客戶端的唯一標(biāo)識,即。 showImg(https://segmentfault.com/img/bV8riL?w=800&h=444); 在技術(shù)面試中,經(jīng)常被問到說說Cookie和Session的區(qū)別...

    microelec 評論0 收藏0
  • Laravel Dependency Injection (依賴注入) 概念詳解

    摘要:依賴注入并不限于構(gòu)造函數(shù)作為經(jīng)驗,注入最適合必須的依賴關(guān)系,比如示例中的情況注入最適合可選依賴關(guān)系,比如緩存一個對象實例。 本文翻譯自 Symfony 作者 Fabien Potencier 的 《Dependency Injection in general and the implementation of a Dependency Injection Container in P...

    Fundebug 評論0 收藏0
  • cookie與session的使用(詳解

    摘要:什么是用來存儲客戶端的一小段文本是一門客戶端的技術(shù)因為是存儲在客戶端瀏覽器中的是為了實現(xiàn)客戶端與服務(wù)器端之間的狀態(tài)的保持技術(shù),不安全,不要使用存儲敏感信息比如登錄狀態(tài)和登錄信息一些敏感的數(shù)據(jù)應(yīng)該存儲在服務(wù)器端的值從哪里來的當(dāng)你訪問一個網(wǎng)站這 什么是cookie, 用來存儲客戶端的一小段文本是一門客戶端的技術(shù) 因為cookie是存儲在客戶端瀏覽器中的是為了實現(xiàn) 客戶端與服務(wù)器端之間的狀態(tài)...

    liujs 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<