• php里少用到的session_module_name,以及session的key值限制,简单将session存储为json格式数据的方法


    这个函数的作用就是动态的设置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 变量不能被存储在会话中.

    序列化句柄 (phpphp_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
    %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;
        }
    }
  • 相关阅读:
    【原】相煎何太急——input的blur事件与button的click事件
    【原】jQuery与CSS自动生成验证码
    【转】HTML转义字符大全
    【原】来自于一位前端“布道者”的建议
    【原】如何在jQuery中实现闭包
    【转】Web前端研发工程师编程能力飞升之路
    【原】git如何删除本地和远程的仓库
    H5不同样式新闻垂直滚动效果
    mui防止软键盘弹起方法
    js显示对象所有属性和方法的函数
  • 原文地址:https://www.cnblogs.com/kudosharry/p/3753649.html
Copyright © 2020-2023  润新知