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\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

时间: 2024-12-13 23:04:01

php里少用到的session_module_name,以及session的key值限制,简单将session存储为json的方法的相关文章

MySQLWorkbench里的稀奇事之timestamp的非空默认值

在创建表时,某字段为非空时间戳,timestamp not null 问题来了,使用workbench建表时,如果值非空,是需要有一个默认值的,不然会报错. 那么,如果是更新时自动填充可以使用DEFAULT ON UPDATE CURRENT_TIMESTAMP,而只在INSERT时插入,不更新则使用CURRENT_TIMESTAMP: 问题是,如果不想使用CURRENT_TIMESTAMP怎么办泥? `end_time` timestamp NOT NULL DEFAULT '0000-00-

少部分手机浏览器对于COOKIE支持不够导致服务端无法读取session的解决方案

相信大家都遇到过这样的问题,有手机浏览器的问题导致服务端SESSION读取不正常,目前在项目中的解决方法是采取H5手机本地存储唯一KEY解决的 代码片段 //定义json格式字符串 var userData = { name: "sankyu Name", account:"sankyu", level:1. disabled:true }; //存储userData数据 localStorage.setItem("userData",JSON.

[LC] 112题 路径总和(在二叉树里判断是否有哪条路径之和等于某个值)

①题目 给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和. 说明: 叶子节点是指没有子节点的节点. 示例: 给定如下二叉树,以及目标和 sum = 22, 返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2. ②思路 用总和sum去减去每次遍历时的根值 ③代码 1 class Solution { 2 public boolean hasPathSum(TreeNode root, int s

jquery里的attr和prop的用法注意,解决用attr移除checked选中状态失败的方法

$(":radio").removeAttr('checked');    $(":radio").attr('checked','true');    实际问题:在使用removeAttr()移除了radio的checked属性后,使用attr()重新增加不起作用:    解决:    $(":radio").removeAttr('checked');    $("input:radio").prop('checked',

php里input数组的应用

一般我们使用input传递表单数据时,可以使用<input name="xxx[]" value="1"><input name="xxx[]" value="2">,来获取$_POST['xxx']为一个数组对象,数据对应关系跟input在表单里的顺序相关. 如果要使用指定key值的数组,可以使用<input name="xxx[a]" value="1"

大型网站架构改进历程:存储的瓶颈(五)

摘要:什么是大型网站,从网站的技术角度考虑这个问题人们很容易犯一个毛病就是认为网站的访问量是衡量的指标,懂点行的人也许会认为是网站在单位时间里的并发量的大小来作为指标,如果按这些标准那么像hao123网站就是了. [编者按]本文转自博客园的 夏天的森林,在看这篇之前,大家可以移步看 大型网站架构改进历程:存储的瓶颈(一).(二).(三).(四). 上文里我遗留了两个问题,一个问题是数据库做了水平拆分以后,如果我们对主键的设计采取一种均匀分布的策略,那么它对于被水平拆分出的表后续的查询操作将有何种

关于大型网站技术演进的思考(五)--存储的瓶颈(5)

原引:http://www.cnblogs.com/sharpxiajun/p/4265853.html 上文里我遗留了两个问题,一个问题是数据库做了水平拆分以后,如果我们对主键的设计采取一种均匀分布的策略,那么它对于被水平拆分出的表后续的查询操作将有何种影响,第二个问题就是水平拆分的扩容问题.这两个问题在深入下去,本系列就越来越技术化了,可能最终很多朋友读完后还是没有找到解决实际问题的启迪,而且我觉得这些问题都是像BAT这样巨型互联网公司才会认真思考的,因此本篇我打算换个角度来阐述本文的后续内

互联网系统的通用架构笔记

接入层session设计原则: 1.Session—读写请求使用的上下文对象,称之会话. 业务总有状态的:用户下单购买.登录状态.好友状态.消息发送情况等: 这些有状态的信息随用户操作变化. 单机环境下: 不存在session共享问题: 处理简单: session保存在内存: 高可用不能保证(进程挂掉.宕机.session丢失不可用). 集群设计: --session复制: 所有接入层服务器之间同步session数据: 每台接入服务器都保存用户全量的session数据: 用户只需访问一台机器,获

哈希表的原理与实现

[转自]:http://my.oschina.net/chape/blog/132533 目录[-] 哈希表的原理与实现 一致性 hash 算法 基本场景 hash 算法和单调性 consistent hashing 算法的原理 虚拟节点 小结 分布式哈希算法 哈希函数 哈希表 分布式哈希表 哈希表的工作原理与常用操作 基础操作 应用举例 哈希表的原理与实现 一列键值对数据,存储在一个table中,如何通过数据的关键字快速查找相应值呢?不要告诉我一个个拿出来比较key啊,呵呵. 大家都知道,在所