PHP中的session有效期默認(rèn)是1440秒(24分鐘),也就是說(shuō),客戶端超過(guò)24分鐘沒(méi)有刷新,當(dāng)前session就會(huì)失效。很明顯,這是不能滿足需要的。 一個(gè)已知管用的方法是,使用session_set_save_handler,接管所有的session管理工作,一般是把session信息存儲(chǔ)到數(shù)據(jù)庫(kù),這樣可以通過(guò)SQL語(yǔ)句來(lái)刪除所有過(guò)期的session,精確地控制session的有效期。這也是基于PHP的大型網(wǎng)站常用的方法。那么接下來(lái)將具體講解如何使用session_set_save_handler;
session_set_save_handler---設(shè)置用戶級(jí) session 存儲(chǔ)函數(shù)
函數(shù)原型 void session_set_save_handler (string open, string close, string read, string write, string destroy, string gc)
session_set_save_handler() 設(shè)置用戶級(jí) session 存儲(chǔ)函數(shù),用于存儲(chǔ)和取回 session 相關(guān)的數(shù)據(jù). 用于那些使用不同于 PHP Session 指定的存儲(chǔ)方式的情況.
例如,在本地?cái)?shù)據(jù)庫(kù)存儲(chǔ) session 數(shù)據(jù). 注意: 你必須設(shè)置 php.ini 里面的 session.save_handler配置參數(shù)來(lái)讓 session_set_save_handler() 正常工作.默認(rèn)配置是
session.save_handler = files, 如果想要使用自定義的處理器(如基于數(shù)據(jù)庫(kù)的處理器),可用"user"。
函數(shù)原型 void session_set_save_handler (string open, string close, string read, string write, string destroy, string gc)
下面介紹該函數(shù)的每個(gè)參數(shù)的意義 ,每個(gè)參數(shù)都是一個(gè)回調(diào)函數(shù),否則沒(méi)意義:
string open 在運(yùn)行session_start()時(shí)執(zhí)行。
string close 在腳本執(zhí)行完成或調(diào)用session_write_close() 或 session_destroy()時(shí)被執(zhí)行,即在所有session操作完后被執(zhí)行。
string read 在運(yùn)行session_start()時(shí)執(zhí)行,因?yàn)樵趕ession_start時(shí),會(huì)去read當(dāng)前session數(shù)據(jù)。
string write 此函數(shù)在腳本結(jié)束和使用session_write_close()強(qiáng)制提交SESSION數(shù)據(jù)時(shí)執(zhí)行。
string destroy 在運(yùn)行session_destroy()時(shí)執(zhí)行即銷毀一個(gè)會(huì)話中的全部數(shù)據(jù)時(shí)執(zhí)行。
string gc 執(zhí)行概率由session.gc_probability 和 session.gc_divisor的值決定,時(shí)機(jī)是在open,read之后,session_start會(huì)相繼執(zhí)行open,read和gc。
備注:session.gc_probability = 1
session.gc_divisor = 100
定義在每次初始化會(huì)話時(shí),啟動(dòng)垃圾回收程序的概率。 這個(gè)收集概率計(jì)算公式如下:session.gc_probability/session.gc_divisor 對(duì)會(huì)話頁(yè)面訪問(wèn)越頻繁,概率就應(yīng)當(dāng)越小。建議值為1/1000~5000。
以下,則是具體的簡(jiǎn)單應(yīng)用:
$session_mysql_conn = null;
$session_mysql_host = "127.0.0.1";
$session_mysql_user = "root";
$session_mysql_pwd = "root";
$session_mysql_db = "session";
$session_mysql_flag = false;
function open($save_path, $session_name)
{
global $session_mysql_host;
global $session_mysql_user;
global $session_mysql_pwd;
global $session_mysql_db;
if(null == $session_mysql_host
|| null == $session_mysql_user
|| null == $session_mysql_db)
return false;
global $session_mysql_conn;
$session_mysql_conn = mysql_connect($session_mysql_host, $session_mysql_user, $session_mysql_pwd);
if(false == $session_mysql_conn)
return (false);
if(false == mysql_select_db($session_mysql_db, $session_mysql_conn))
{
mysql_close($session_mysql_conn);
$session_mysql_conn = null;
return (false);
}
return(true);
}
function close()
{
return(true);
}
function read($id)
{
global $session_mysql_conn;
if(null == $session_mysql_conn)
return null;
$select_sql = "select value from session where id = '$id'";
$result = mysql_query($select_sql, $session_mysql_conn);
if(false == $result)
return null;
if(0 == mysql_num_rows($result))
return null;
$row = mysql_fetch_row($result);
if(empty($row))
return null;
$res = $row[0];
mysql_free_result($result);
//echo "session_mysql_read:$id = $res ";
return $res;
}
function write($id, $sess_data)
{
//echo "session_mysql_write $id = $sess_data ";
global $session_mysql_conn;
global $session_mysql_flag;
if(null == $session_mysql_conn)
return false;
$value = mysql_real_escape_string($sess_data);
$write_sql="update session set value = '$value' where id = '$id'";
if(false == $session_mysql_flag)
{
$select_sql = "select count(id) from session where id = '$id'";
$result = mysql_query($select_sql, $session_mysql_conn);
if(false == $result)
return false;
$row = mysql_fetch_row($result);
if(empty($row))
return false;
if($row[0] == 0)
{
$write_sql="insert into session (id,value) values ('$id', '$value')";
}
else
{
$session_mysql_flag = true;
}
}
return mysql_query($write_sql, $session_mysql_conn);
}
function destroy($id)
{
global $session_mysql_conn;
if(null == $session_mysql_conn)
return false;
mysql_close($session_mysql_conn);
$session_mysql_conn = null;
}
function gc($maxlifetime)
{
global $session_mysql_conn;
if(null == $session_mysql_conn)
return false;
$t = time() - $maxlifetime;
$d = date("Y-m-d h:i:s",$t);
$delete_sql = "delete from session where ctime < '$d'";
return mysql_query($delete_sql, $session_mysql_conn);
}
function set_session_mysql($s_mysql_host, $s_mysql_user, $s_mysql_pwd, $s_mysql_db)
{
global $session_mysql_host;
global $session_mysql_user;
global $session_mysql_pwd;
global $session_mysql_db;
$session_mysql_host = $s_mysql_host;
$session_mysql_user = $s_mysql_user;
$session_mysql_pwd = $s_mysql_pwd;
$session_mysql_db = $s_mysql_db;
session_module_name('user');
session_set_save_handler("open", "close", "read", "write", "destroy", "gc");
}
set_session_mysql("127.0.0.1","root","root","session");
session_start();
$_SESSION['A']="AAA";
$_SESSION['B']="AAA";
$_SESSION['C']="AAA";
?>
數(shù)據(jù)庫(kù)中的表結(jié)構(gòu):
/*
* usage as:
*
* date_default_timezone_set("PRC");
* set_session_mysql("localhost:3306", "root", "", "db");
* session_start();
*
* #session table
*
CREATE TABLE `session` (
`id` varchar(100) NOT NULL DEFAULT '',
`value` mediumblob NOT NULL,
`ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURREN T_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
*/