Session 存儲(chǔ)方式
在 php.ini 文件中挪蹭,進(jìn)行配置。
- session.save_handler = files
- session.save_path = "N;MODE;/tmp"
這兩個(gè)參數(shù)可以在 PHP 中通過(guò) ini_set 來(lái)設(shè)置固逗,不用直接覆蓋原 php.ini 中的值。
注釋:
- N 表示多級(jí)目錄,值為數(shù)字嘉赎。
- MODE 表示創(chuàng)建的 Session 文件權(quán)限。
- /tmp 表示 Session 存儲(chǔ)路徑于樟。
PHP官網(wǎng)的解釋:
此指令還有一個(gè)可選的 N 參數(shù)來(lái)決定會(huì)話文件分布的目錄深度公条。
例如,設(shè)定為 '5;/tmp' 將使創(chuàng)建的會(huì)話文件和路徑類似于 /tmp/4/b/1/e/3/sess_4b1e384ad74619bd212e236e52a5a174If迂曲。
要使用 N 參數(shù)靶橱,必須在使用前先創(chuàng)建好這些目錄。
在 ext/session 目錄下有個(gè)小的 shell 腳本名叫 mod_files.sh路捧,windows 版本是 mod_files.bat 可以用來(lái)做這件事关霸。
此外注意如果使用了 N 參數(shù)并且大于 0,那么將不會(huì)執(zhí)行自動(dòng)垃圾回收鬓长,更多信息見(jiàn) php.ini谒拴。
另外如果用了 N 參數(shù),要確保將 session.save_path 的值用雙引號(hào) "quotes" 括起來(lái)涉波,因?yàn)榉指舴痔?hào)( ;)在 php.ini 中也是注釋符號(hào)英上。
文件儲(chǔ)存模塊默認(rèn)使用 mode 600 創(chuàng)建文件炭序。
通過(guò) 修改可選參數(shù) MODE 來(lái)改變這種默認(rèn)行為: N;MODE;/path ,其中 MODE 是 mode 的八進(jìn)制表示苍日。
MODE 設(shè)置不影響進(jìn)程的掩碼(umask)惭聂。
Caution:使用以上描述的可選目錄層級(jí)參數(shù) N 時(shí)請(qǐng)注意,對(duì)于絕大多數(shù)站點(diǎn)相恃,
大于1或者2的值會(huì)不太合適——因?yàn)檫@需要?jiǎng)?chuàng)建大量的目錄:例如辜纲,值設(shè)置為 3 需要在文件系統(tǒng)上創(chuàng)建 64^3 個(gè)目錄,將浪費(fèi)很多空間和 inode拦耐。
僅僅在絕對(duì)肯定站點(diǎn)足夠大時(shí)耕腾,才可以設(shè)置 N 大于2。
Session 生命周期
第一種是通過(guò)程序
- session_destory()方法清除所有session
- unset(session['x'])來(lái)清除指定的session['x']杀糯。
第二種是通過(guò)編輯瀏覽器
- 關(guān)閉后會(huì)直接清除所有session
Session 垃圾回收機(jī)制
- session.gc_maxlifetime
- session.gc_probability
- session.gc_divisor
Garbage Collection 垃圾回收:
session.gc_divisor 與 session.gc_probability 合起來(lái)定義了在每個(gè)會(huì)話初始化時(shí)啟動(dòng) GC 進(jìn)程的概率。
此概率用 gc_probability/gc_divisor 計(jì)算得來(lái)固翰。例如 1/1000 意味著在每個(gè)請(qǐng)求中有 0.1% 的概率啟動(dòng) GC 進(jìn)程狼纬。
GC的工作,就是掃描所有的session信息骂际, 用當(dāng)前時(shí)間減去session的最后修改時(shí)間(modified date)疗琉,同session.gc_maxlifetime參數(shù)進(jìn)行比較,
如果生存時(shí)間已經(jīng)超過(guò)gc_maxlifetime歉铝,就把該session刪除盈简。
Session 共享
- Redis [分布式]
- Memcache [分布式]
以Memcache 為例:
多臺(tái)機(jī)器共用一個(gè) memcache 這樣的好處,就是在并發(fā)大訪問(wèn)的情況下太示,還能防止單臺(tái)機(jī)器送火,因?yàn)榉磸?fù)創(chuàng)建和打開(kāi)SESSION文件,造成的IO壓力先匪,之前測(cè)試過(guò)种吸,對(duì)于緩實(shí)IO壓力很有效。
//配置 php.ini呀非,配置后記得重啟
//memcache Ip(127.0.0.1) Port(11211)
session.save_handler = memcache
session.save_path = "tcp://127.0.0.1:11211"
//set_session.php
session_start();
$_SESSION['name'] = 'Bihu';
print $_SESSION['name'];
print "<br>";
print session_id();
//運(yùn)行后輸出
//Bihu
//9325ag3rvunvhl7c2pfd3u27n0
//表示:Session 存儲(chǔ)成功
//get_session.php
$memcache = new Memcache();
$memcache->connect('127.0.0.1', 11211);
$data = $memcache->get('9325ag3rvunvhl7c2pfd3u27n0');
print $data;
//運(yùn)行后輸出
//name|s:4:"Bihu"; (解析數(shù)據(jù)即可[首先要先了解Session數(shù)據(jù)結(jié)構(gòu)])
//表示:Session 獲取成功
//附上解析數(shù)據(jù)方法
function unserialize_php($session_data)
{
$return_data = array();
$offset = 0;
while ($offset < strlen($session_data)) {
if (!strstr(substr($session_data, $offset), "|")) {
throw new Exception("invalid data, remaining: " .substr($session_data, $offset));
}
$pos = strpos($session_data, "|", $offset);
$num = $pos - $offset;
$varname = substr($session_data, $offset, $num);
$offset += $num + 1;
$data = unserialize(substr($session_data, $offset));
$return_data[$varname] = $data;
$offset += strlen(serialize($data));
}
return $return_data;
}
$un_data = unserialize_php($data);
echo '<pre>';
var_dump(unserialize_php($un_data));
//輸出數(shù)據(jù)
//array(1) {
// ["name"]=>
// string(4) "Bihu"
//}
Thanks ~