这个函数的作用就是动态的设置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
php里少用到的session_module_name,以及session的key值限制,简单将session存储为json的方法