这个函数的作用就是动态的设置php.ini里的session_save_handler,配合session_set_savepath可以在程序里自由配置session的后台方式。
session_cache_expire与session_cache_limiter函数是配置session缓存时间与头信息的,比如private,public,nocache
与ini_set函数类似
都要在session_start()之前调用
session.save_handler = files
session.save_path = "E:/wamp/tmp/test"session.save_handler = memcache
session.save_path = "tcp://192.168.1.188:11211"switch($session->save_handler){
case ‘memcache‘:
session_module_name(‘memcache‘);
session_save_path($session->save_path);
//自定义的时候
//SessionMemcache::init($session->save_path);
break;
case ‘files‘:
if($session->save_path){
if(!file_exists($session->save_path)){
mkdir($session->save_path, true);
if(!file_exists($session->save_path){
exit(‘session_path is not exits‘);
}
}
session_module_name(‘files‘);
session_save_path($session->save_path);
}
break;
default:
break;
}
由于php的session扩展没有json的序列化方式,即使memcached有也不能实现session数据的json化。
使用session_set_save_handler可以在write里改写,但是这里的输入参数已经是序列化后的,所以要自己分解。
只要session_start()执行就会按照open,read,PHP的其他输出,write,close的顺序执行。
因为会话数据是被序列化的, resource
变量不能被存储在会话中.
序列化句柄 (php 和 php_binary) 会受到 register_globals
的限制. 而且,数字索引或者字符串索引包含的特殊字符(| 和 !) 不能被使用.
使用这些字符将脚本执行关闭时的最后出现错误. php_serialize 没有这样的限制.php_serialize 从
PHP 5.5.4 以后可用.
我还想半天session的反序列化,完美的方法不太好处理,这里限制session的所有键值都避免使用} |
;等敏感字符,没有经过完全测试,可能在复杂结构下会有问题,执行比原生的速度慢,而且随着数据量效率更差。
解决这个问题还是要从C扩展实现,不过临时的解决方案可以尝试一下。
class SessionMemcache{
private static $_client = null;
private static $_config = null;
private static $_expire = 1800;
private static $is_json = false;/**
* 构造函数
* @param unknown $session
*/
private function __construct(){
session_set_save_handler(
array($this, ‘open‘),
array($this, ‘close‘),
array($this, ‘read‘),
array($this, ‘write‘),
array($this, ‘destroy‘),
array($this, ‘gc‘)
);
}public static function init($configArray, $expire, $is_json = false){
if(self::$_client == null){
new self();
self::$_config = $configArray;
self::$_expire = $expire;
self::$is_json = $is_json;
}
//register_shutdown_function(‘session_write_close‘);
}/**
* 打开session连接
* @return boolean
*/
public function open($savePath, $sessionName){
self::$_client = Bootstrap::memFaction(self::$_config);
return true;
}/**
* 关闭session连接
* @return boolean
*/
public function close(){
return true;
}/**
* 读取session数据
* @param unknown $id
* @return Ambigous <NULL, unknown>
*/
public function read($id){
$data = self::$_client->get($id);
if(strlen($data) > 0 && self::$is_json){
$data = $this->session_json_decode(json_decode($data,true));
}
return ($data === false ? null : $data);
}/**
* 保存session数据
* @param unknown $id
* @param unknown $value
*/
public function write($id, $value)
{
// $x = file_get_contents(ROOT_PATH . ‘/temp/sess.txt‘);
// file_put_contents(ROOT_PATH . ‘/temp/sess.txt‘, sprintf("%s\n%s", $x, $value));
//file_put_contents("D:/aa.txt", var_export($value,true));
if(self::$is_json){
$value = $this->session_json_encode($value);
}
//file_put_contents("D:/bb.txt", var_export($value,true));
if (extension_loaded(‘memcached‘)) {
$flag = self::$_client->set($id, $value, self::$_expire);
} else {
$flag = self::$_client->set($id, $value, 0, self::$_expire);
}
return $flag;
}public function destroy($id)
{return self::$_client->delete($id);
}
public function gc($maxLifetime)
{return true;
}
protected function session_json_encode($value)
{
//按;XXX|切分字符串,对第一个和最后一个做特殊处理
preg_match_all(‘/[};](\w+)\|/‘,$value,$matchs);//var_dump($matchs);exit;
$serializeStr = "a:" . (count($matchs[0])+1) .":{";
$str_copy = $value;
foreach($matchs[0] as $k => $v){
$strBefore = strstr($str_copy,$v,true);
$strAfter = strstr($str_copy,$v);
$str_copy = substr($strAfter,strlen($v));if($k == 0){
$strOneBefore = strstr($strBefore,‘|‘,true);
$strOneAfter = strstr($strBefore,‘|‘);
$strOneAfter = substr($strOneAfter,1);
if($v[0] == ‘}‘){
$serializeStr .= ‘s:‘ . strlen($strOneBefore) . ‘:"‘ .$strOneBefore . ‘";‘ . $strOneAfter . ‘}‘;
}else{
$serializeStr .= ‘s:‘ . strlen($strOneBefore) . ‘:"‘ .$strOneBefore . ‘";‘ . $strOneAfter . ‘;‘;
}
}else{
if($v[0] == ‘}‘){
$serializeStr .= "s:" . strlen($matchs[1][$k-1]) . ‘:"‘ . $matchs[1][$k-1] . ‘";‘ . $strBefore . ‘}‘;
}else{
$serializeStr .= "s:" . strlen($matchs[1][$k-1]) . ‘:"‘ . $matchs[1][$k-1] . ‘";‘ . $strBefore . ‘;‘;
}
}
if(!isset($matchs[0][$k+1])){
$serializeStr .= "s:" . strlen($matchs[1][$k]) . ‘:"‘ . $matchs[1][$k] . ‘";‘ . substr($strAfter,strlen($v)) . ‘}‘;
}
//$delimit[]=$strBefore;
}
//$delimit[] = substr($strAfter,strlen($v));
//var_dump($delimit);exit;
//var_dump(unserialize($serializeStr));exit;
//echo $serializeStr;exit;
return json_encode(unserialize($serializeStr));
}function session_json_decode(array $data){
$ree = ‘‘;
foreach($data as $k => $v){
if(is_array($v)){
$ree .= $k . ‘|‘ . serialize($v);
}
elseif(is_string($v)){
$ree .= $k . ‘|s:‘ . strlen($k) . ‘:"‘ . $v . ‘";‘;
}
elseif(is_int($v)){
$ree .= $k . ‘|i:‘ . $v . ‘;‘;
}
elseif(is_float($v)){
$ree .= $k . ‘|d:‘ . $v . ‘;‘;
}
elseif(is_double($v)){
$ree .= $k . ‘|d:‘ . $v . ‘;‘;
}
}
return $ree;
}
}
php里少用到的session_module_name,以及session的key值限制,简单将session存储为json的方法,布布扣,bubuko.com