好久没有写博客了,今天来一片php使用redis共享session
网上的php将session存放在redis的方法,大多数只是指出了如何存放,并没有涉及到如何存放json格式
我根据网上的资料,整理出自己的代码,使得session能够以json格式存放在redis里面,方便和其他语言的共享
<?php class RedisSessionHandler implements SessionHandlerInterface{ private $redis; private $config; private $namespace; private $session_id = null; private $maxlifetime = null; public function __construct($config) { //初始化redis $this->config = array( "namespace"=>"", "host"=>"127.0.0.1", "port"=>"6789", "auth"=>"", "db"=>0 ); $this->config = array_merge($this->config,$config); $this->redis = new Redis(); $this->redis->connect($this->config["host"],$this->config["port"]); if(!empty($this->config["auth"])) { $ret = $this->redis->auth($this->config["auth"]); if(!$ret) { return false; } $this->redis->select($this->config["db"]); } //设置当前的sessionid生成的命名空间 $this->namespace = $this->config["namespace"]; if(!empty($this->namespace)) { $this->namespace .=":"; } //设置初始化的session_id if(empty($session_name)) { $session_name = ini_get("session.name"); } //没有设置过session,新的会话,需要重新生成sessionid if ( empty($_COOKIE[$session_name]) ) { $this->session_id = true; } } public function open($savePath, $sessionName){ $connect = $this->redis->connect($this->config["host"],$this->config["port"]); if(!$connect) return false; if(!empty($this->config["auth"])) { $ret = $this->redis->auth($this->config["auth"]); if(!$ret) { return false; } $this->redis->select($this->config["db"]); } //在初次设置的时候,重设PHP本身的session_id并判断session_id是否已经存在 $id = session_id(); if($this->session_id && $this->session_id != $id){ do{ $this->session_id = $this->session_id(); }while($this->redis->exists($this->namespace.$this->session_id)); session_id($this->session_id); } //设置生成周期 $this->maxlifetime = ini_get("session.gc_maxlifetime"); return true; } public function close(){ $this->redis->close(); return true; } public function read($id){ $data = json_decode($this->redis->get($this->namespace.$id),TRUE); return serialize($data); } public function write($id, $data){ $json = json_encode(unserialize($data),JSON_UNESCAPED_UNICODE|JSON_NUMERIC_CHECK); return $this->redis->setex($this->namespace.$id,$this->maxlifetime,$json); } public function destroy($id){ $this->redis->delete($this->namespace.$id); return true; } public function gc($maxlifetime){ return true; } /** * 生成guid */ private function session_id(){ $uid = uniqid("", true); $data = $this->namespace; $data .= $_SERVER["REQUEST_TIME"]; $data .= $_SERVER["HTTP_USER_AGENT"]; $data .= $_SERVER["SERVER_ADDR"]; $data .= $_SERVER["SERVER_PORT"]; $data .= $_SERVER["REMOTE_ADDR"]; $data .= $_SERVER["REMOTE_PORT"]; $hash = strtoupper(hash("ripemd128", $uid . md5($data))); return substr($hash,0,32); } } $handler = new RedisSessionHandler($param); session_set_save_handler($handler, true); session_start(); /* if(empty($_SESSION)){ $_SESSION["test"]= ["a"=>1,"b"=>2]; } var_dump($_SESSION); */
需要把session.serialize_handler 设置为php_serialize
原理:自己写代码实现SessionHandlerInterface 接口,在写入和读出时进行格式转换,使得session能够以json格式存放在redis里面。
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: string 转 hex string 并转回来
- 下一篇: 树形和仿树形下拉框