PHP中的session有效期默認是1440秒(24分鐘),也就是說,客戶端超過24分鐘沒有刷新,當前session就會失效。很明顯,這是不能滿足需要的。 一個已知管用的方法是,使用session_set_save_handler,接管所有的session管理工作,一般是把session信息存儲到數(shù)據(jù)庫,這樣可以通過SQL語句來刪除所有過期的session,精確地控制session的有效期。這也是基于PHP的大型網(wǎng)站常用的方法。那么接下來將具體講解如何使用session_set_save_handler;
session_set_save_handler---設(shè)置用戶級 session 存儲函數(shù)
函數(shù)原型 void session_set_save_handler (string open, string close, string read, string write, string destroy, string gc)
session_set_save_handler() 設(shè)置用戶級 session 存儲函數(shù),用于存儲和取回 session 相關(guān)的數(shù)據(jù). 用于那些使用不同于 PHP Session 指定的存儲方式的情況.
例如,在本地數(shù)據(jù)庫存儲 session 數(shù)據(jù). 注意: 你必須設(shè)置 php.ini 里面的 session.save_handler配置參數(shù)來讓 session_set_save_handler() 正常工作.默認配置是
session.save_handler = files, 如果想要使用自定義的處理器(如基于數(shù)據(jù)庫的處理器),可用"user"。
函數(shù)原型 void session_set_save_handler (string open, string close, string read, string write, string destroy, string gc)
下面介紹該函數(shù)的每個參數(shù)的意義 ,每個參數(shù)都是一個回調(diào)函數(shù),否則沒意義:
string open 在運行session_start()時執(zhí)行。
string close 在腳本執(zhí)行完成或調(diào)用session_write_close() 或 session_destroy()時被執(zhí)行,即在所有session操作完后被執(zhí)行。
string read 在運行session_start()時執(zhí)行,因為在session_start時,會去read當前session數(shù)據(jù)。
string write 此函數(shù)在腳本結(jié)束和使用session_write_close()強制提交SESSION數(shù)據(jù)時執(zhí)行。
string destroy 在運行session_destroy()時執(zhí)行即銷毀一個會話中的全部數(shù)據(jù)時執(zhí)行。
string gc 執(zhí)行概率由session.gc_probability 和 session.gc_divisor的值決定,時機是在open,read之后,session_start會相繼執(zhí)行open,read和gc。
備注:session.gc_probability = 1
session.gc_divisor = 100
定義在每次初始化會話時,啟動垃圾回收程序的概率。 這個收集概率計算公式如下:session.gc_probability/session.gc_divisor 對會話頁面訪問越頻繁,概率就應(yīng)當越小。建議值為1/1000~5000。
以下,則是具體的簡單應(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ù)庫中的表結(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;
*/