PHP下利用共享内存处理session的代码

jackxiang 2009-7-22 18:15 | |

<?php
define("SESSION_PATH_HANDLE","session.data");
define("SESSION_INDEX_HANDLE","index.data");
define("SESSION_INDEX_SIZE",1048576);
define("SESSION_DATA_SIZE",10485760);
define("SHARED_SESS_TIME",3600);
class ShareMemSession
{

function init()
{
if(!file_exists(SESSION_INDEX_HANDLE))
{
$handle=fopen(SESSION_INDEX_HANDLE,"wb");
fwrite($handle,"I will use this file for session index");
fclose($handle);
$shm_index_key=ftok(SESSION_INDEX_HANDLE,"c");
$sem_index_id=sem_get($shm_index_key,1,0644,0);
sem_acquire($sem_index_id);
$shm_index_id=shm_attach( $shm_index_key,SESSION_INDEX_SIZE);
$session_index=array();
$shm_put_var($shm_index_id,1,$session_index);
shm_detach($shm_index_id);
sem_release($sem_index_id);
}
if(!file_exists(SESSION_PATH_HANDLE))
{
$handle=fopen(SESSION_PATH_HANDLE,"wb");
fwrite($handle,"I will use this file for session");
fclose($handle);
$shm_data_key=ftok(SESSION_PATH_HANDLE,"c");
$sem_data_id=sem_get($shm_data_key,1,0644,0);
$shm_data_id=shm_attach( $shm_data_key,SESSION_DATA_SIZE);
shm_detach($shm_data_id);
sem_release($sem_data_id);
}
ini_set('session.use_trans_sid', 0);
//设置垃圾回收最大生存时间
ini_set('session.gc_maxlifetime', SHARED_SESS_TIME);

//使用 COOKIE 保存 SESSION ID 的方式
ini_set('session.use_cookies', 1);
ini_set('session.cookie_path', "/");
//多主机共享保存 SESSION ID 的 COOKIE
// ini_set('session.cookie_domain', $domain);
session_module_name("user");
session_set_save_handler(
array("ShareMemSession", "open"),
array("ShareMemSession", "close"),
array("ShareMemSession", "read"),
array("ShareMemSession", "write"),
array("ShareMemSession", "destroy"),
array("ShareMemSession", "gc")
);

}
function open($save_path, $session_name)
{
return true;
}

function close(){
return true;
}

function read($session_id)
{
$tmp_session_id=-1;
//first ,I will read session index from share_mem
$shm_index_key=ftok(SESSION_INDEX_HANDLE,"c");
$sem_index_id=sem_get($shm_index_key,1,0644,0);
sem_acquire($sem_index_id);
$shm_index_id=shm_attach( $shm_index_key,SESSION_INDEX_SIZE);
$session_index=shm_get_var($shm_index_id,1);

if($session_index)
{
if(!is_array($session_index) || !isset($session_index[$session_id])) return "";
$tmp_session_id=$session_index[$session_id]["session_hash_id"];//得到当前session的hash id
$session_index[$session_id]["lastvisit"]=time();
shm_put_var($shm_index_id,1,$session_index);
shm_detach($shm_index_id);
sem_release($sem_index_id);
}
else
{
shm_detach($shm_index_id);
sem_release($sem_index_id);
return "";
}
$shm_data_key=ftok(SESSION_PATH_HANDLE,"c");
$sem_data_id=sem_get($shm_data_key,1,0644,0);
sem_acquire($sem_data_id);
$shm_data_id=shm_attach( $shm_data_key,SESSION_DATA_SIZE);
$result=shm_get_var($shm_data_id,$tmp_session_id);
shm_detach($shm_data_id);
sem_release($sem_data_id);
return $result;
}

function write($session_id, $data_value)
{
$tmp_session_id=-1;
//first ,I will read session index from share_mem
$shm_index_key=ftok(SESSION_INDEX_HANDLE,"c");
$sem_index_id=sem_get($shm_index_key,1,0644,0);
sem_acquire($sem_index_id);
$shm_index_id=shm_attach( $shm_index_key,SESSION_INDEX_SIZE);
$session_index=shm_get_var($shm_index_id,1);
if($session_index)
{
if(is_array($session_index) && isset($session_index[$session_id]))
{
$tmp_session_id=$session_index[$session_id]["session_hash_id"];//得到当前session的hash id
$session_index[$session_id]["lastvisit"]=time();
}
else
{
$hash_id=ShareMemSession::hash($session_id);
while(array_search($hash_id,$session_index))
{
if ($hash_id<5000)
$hash_id=5000;
else
$hash_id++;
}
$tmp_index=array();
$tmp_index["session_hash_id"]=$hash_id;
$tmp_index["lastvisit"]=time();
$session_index[$session_id]=$tmp_index;
$tmp_session_id=$hash_id;
}

shm_put_var($shm_index_id,1,$session_index);

}
else
{
shm_detach($shm_index_id);
sem_release($sem_index_id);
return false;
}
$shm_data_key=ftok(SESSION_PATH_HANDLE,"c");
$sem_data_id=sem_get($shm_data_key,1,0644,0);
sem_acquire($sem_data_id);
$shm_data_id=shm_attach( $shm_data_key,SESSION_DATA_SIZE);
$result=shm_put_var($shm_data_id,$tmp_session_id,$data_value);
shm_detach($shm_data_id);
sem_release($sem_data_id);

return true;
}

function destroy($session_id){
$tmp_session_id=-1;
//first ,I will read session index from share_mem
$shm_index_key=ftok(SESSION_INDEX_HANDLE,"c");
$sem_index_id=sem_get($shm_index_key,1,0644,0);
sem_acquire($sem_index_id);
$shm_index_id=shm_attach( $shm_index_key,SESSION_INDEX_SIZE);
$session_index=shm_get_var($shm_index_id,1);

if($session_index)
{
if(is_array($session_index) && isset($session_index[$session_id]))
{
$tmp_session_id=$session_index[$session_id]["session_hash_id"];//得到当前session的hash id
unset($session_index[$session_id]);
shm_put_var($shm_index_id,1,$session_index);
shm_detach($shm_index_id);
sem_release($sem_index_id);
}
}
if($tmp_session_id!=-1)
{
$shm_data_key=ftok(SESSION_PATH_HANDLE,"c");
$sem_data_id=sem_get($shm_data_key,1,0644,0);
sem_acquire($sem_data_id);
$shm_data_id=shm_attach( $shm_data_key,SESSION_DATA_SIZE);
$result=shm_remove_var($shm_data_id,$tmp_session_id);
shm_detach($shm_data_id);
sem_release($sem_data_id);
}
return true;
}

function gc($maxlifetime = SHARED_SESS_TIME)
{
$shm_index_key=ftok(SESSION_INDEX_HANDLE,"c");
$sem_index_id=sem_get($shm_index_key,1,0644,0);
sem_acquire($sem_index_id);
$shm_index_id=shm_attach( $shm_index_key,SESSION_INDEX_SIZE);
$session_index=shm_get_var($shm_index_id,1);
$tmpresult=array();
$check_time=time();
if($session_index)
{
foreach($session_index as $key=>$value)
{
if($value["lastvisit"]+$maxlifetime<$check_time)
$tmpresult[]=array("session_id"=>$key,"hash_id"=>$value["session_hash_id"]);
// $tmp_session_id=$session_index[$session_id]["session_hash_id"];//得到当前session的hash id
// unset($session_index[$session_id]);
}
$shm_data_key=ftok(SESSION_PATH_HANDLE,"c");
$sem_data_id=sem_get($shm_data_key,1,0644,0);
sem_acquire($sem_data_id);
foreach($tmpresult as $item)
{
$tmp_session_id=$item["session_id"];//得到当前session的hash id
unset($session_index[$session_id]);
$result=shm_remove_var($shm_data_id,$item["hash_id"]);
}
shm_put_var($shm_index_id,1,$session_index);


}
shm_detach($shm_index_id);
sem_release($sem_index_id);
shm_detach($shm_data_id);
sem_release($sem_data_id);
return true;
}
function hash($session_id)
{
$length = strlen($string);
//$aim;
$aim = "";
for($loop = 0;$loop < $length;$loop++)
{
$temp = substr($string, $loop, 1);
if (is_numeric($temp))
$aim += $temp;
else
{
$asc = ord($temp);
$aim += $asc;
}
}
return $aim;
}
}
ShareMemSession::init();
?>





session共享大家有什么好的解决方案吗?
1、PHP原生SESSION,NFS共享
2、自定义SESSION,存入数据库
3、更改SESSION配置,存入MEMCACHED

作者:jackxiang@向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除
地址:https://jackxiang.com/post/1853/
版权所有。转载时必须以链接形式注明作者和原始出处及本声明!


最后编辑: jackxiang 编辑于2011-8-10 11:59
评论列表
发表评论

昵称

网址

电邮

打开HTML 打开UBB 打开表情 隐藏 记住我 [登入] [注册]