用mysql内存表来代替php session的类


Posted in PHP onFebruary 01, 2009
<?php 
/** 
@Usage: use some other storage method(mysql or memcache) instead of php sessoin 
@author:lein 
@Version:1.0 
*/ 
session_start(); 
if(!isset($_SESSION['test'])){ 
$_SESSION['test']="123_lein_".date("Y-m-d H:i:s"); 
} class session{ 
//session data 
private $data; 
//engine,mysql or memcache 
private $engine; 
//php session expire time 
private $sessionexpiredTime; 
//current user's session cookie value 
private $sessionID; 
public function session($engineBase=NULL,$engineName='mysql',$storage_name='php_session'){ 
try{ 
$this->sessionexpiredTime = intval(ini_get("session.cache_expire"))*60; 
}catch(Exception $Exception){ 
$this->sessionexpiredTime = 1200; 
} 
@session_start(); 
$this->sessionID=session_id(); 
$className = $engineName."SessionEngine"; 
$this->engine = new $className( 
array( 
'storage_name'=>$storage_name,//mysql table name or memcahce key which stores data; 
'expire_time'=>$this->sessionexpiredTime, 
'data_too_long_instead_value' => '{__DATA IS *$* TO LONG__}' 
), 
$this->sessionID, 
&$engineBase 
); 
$this->init(); 
$this->engine->refresh(); 
$this->engine->cleanup(); 
} 
private function init() 
{ 
$this->data = $this->engine->get(); 
if(emptyempty($this->data)&&!emptyempty($_SESSION)){ 
$this->data = $_SESSION; 
$this->engine->create(false, $this->data); 
} 
else if(emptyempty($this->data)) 
{ 
$this->engine->create(false, $this->data); 
} 
} 
private function __get($nm) 
{ 
if (isset($this->data[$nm])) { 
$r = $this->data[$nm]; 
return $r; 
} 
else 
{ 
return NULL; 
} 
} 
private function __set($nm, $val) 
{ 
$this->data[$nm] = $val; 
$this->engine->set(false, $this->data); 
} 
function __destruct(){ 
$this->data = NULL; 
$this->engine->close(); 
$this->engine = NULL; 
} 
} 
interface SessionEngine 
{ 
/* 
* set varibles 
* @param $arr array,array(varible name=>varible value,...) 
*/ 
public function setVariable($arr); 
/* 
* get session value 
* @param $key string 
*/ 
public function get($key=""); 
/* 
* set session value 
* @param $key string 
* @param $value string 
*/ 
public function set($key="",$value=""); 
/* 
* set session value 
* @param $key string 
* @param $value string 
*/ 
public function create($key="",$value=""); 
/* 
* update the session's invalid time 
* @param $key string 
*/ 
public function refresh($key=""); 
/* 
* close mysql or memcache connection 
*/ 
public function close(); 
/* 
* delete expired sessions 
*/ 
public function cleanup(); 
} 
final class mysqlSessionEngine implements SessionEngine{ 
private $id=""; 
private $storage_name='php_session'; 
private $storage_name_slow='php_session_slow'; 
private $data_too_long_instead_value = '{__DATA IS ~ TO LONG__}';//if data is longer than $max_session_data_length and you are using mysql 4 or below,insert this value into memery table instead. 
private $expire_time=1200; 
private $max_session_data_length = 2048; 
private $conn; 
private $mysql_version; 
public function mysqlSessionEngine($arr=array(),$key="",&$_conn){ 
$this->setVariable($arr); 
$this->id = $key; 
if(emptyempty($this->id)||strlen($this->id)!=32){ 
throw new Exception(__FILE__."->".__LINE__.": Session's cookie name can't be empty and it must have just 32 charactors!"); 
} 
$this->conn = $_conn; 
if(!$this->conn||!is_resource($this->conn)){ 
throw new Exception(__FILE__."->".__LINE__.": Need a mysql connection!"); 
} 
$this->mysql_version = $this->getOne("select floor(version())"); 
if($this->mysql_version<5){ 
$this->max_session_data_length = 255; 
} 
} 
public function setVariable($arr){ 
if(!emptyempty($arr)&&is_array($arr)){ 
foreach($arr as $k=>$v){ 
$this->$k = $v; 
if($k=='storage_name'){ 
$this->storage_name_slow = $v.'_slow'; 
} 
} 
} 
} 
public function get($key=""){ 
if($key=="") $key = $this->id; 
$return = $this->getOne('select value from '.$this->storage_name.' where id="'.$key.'"'); 
if($return==$this->data_too_long_instead_value) 
{ 
$return = $this->getOne('select value from '.$this->storage_name_slow.' where id="'.$key.'"'); 
} 
if(!$return) 
{ 
$mysqlError = mysql_error($this->conn); 
if(strpos($mysqlError,"doesn't exist")!==false) 
{ 
$this->initTable(); 
} 
$return = array(); 
} 
else 
{ 
$return = unserialize($return); 
} 
return $return; 
} 
public function close(){ 
@mysql_close($this->conn); 
} 
public function cleanup(){ 
if($this->mysql_version>4){ 
$sql = 'delete from '.$this->storage_name.' while date_add(time,INTERVAL '.$this->expire_time.' SECOND)<CURRENT_TIMESTAMP()'; 
}else{ 
$sql = 'delete from '.$this->storage_name.' while time+'.$this->expire_time.'<unix_timestamp()'; 
} 
$this->execute($sql); 
} 
public function refresh($key=""){ 
if($this->mysql_version>4){ 
$sql = 'update '.$this->storage_name.' set time=CURRENT_TIMESTAMP() where id="'.$key.'"'; 
}else{ 
$sql = 'update '.$this->storage_name.' set time=unix_timestamp() where id="'.$key.'"'; 
} 
$return = $this->execute($sql); 
if(!$return){ 
$this->initTable(); 
$return = $this->execute($sql,true); 
} 
return $return; 
} 
public function create($key="",$value=""){ 
if($key=="") $key = $this->id; 
if($value != "") $value = mysql_real_escape_string(serialize($value),$this->conn); 
if(strlen($value)>$this->max_session_data_length) throw new Exception(__FILE__."->".__LINE__.": Session data is long than max allow length(".$this->max_session_data_length.")!"); 
if($this->mysql_version>4){ 
$sql = 'replace into '.$this->storage_name.' set value=\''.$value.'\',id="'.$key.'",time=CURRENT_TIMESTAMP()'; 
}else{ 
$sql = 'replace into '.$this->storage_name.' set value=\''.$value.'\',id="'.$key.'",time=unix_timestamp()'; 
} 
$return = $this->execute($sql); 
if(!$return){ 
$this->initTable(); 
$return = $this->execute($sql,true); 
} 
return $return; 
} 
public function set($key="",$value=""){ 
if($key=="") $key = $this->id; 
if($value != "") $value = mysql_real_escape_string(serialize($value),$this->conn); 
$sql = 'update '.$this->storage_name.' set value=\''.$value.'\' where id="'.$key.'"'; 
if(strlen($value)>$this->max_session_data_length) 
{ 
if($this->mysql_version>4){ 
throw new Exception(__FILE__."->".__LINE__.": Session data is long than max allow length(".$this->max_session_data_length.")!"); 
} 
$sql = 'replace into '.$this->storage_name_slow.' set value=\''.$value.'\',id="'.$key.'",time=unix_timestamp()'; 
$this->execute($sql,true); 
$sql = 'update '.$this->storage_name.' set value=\''.$this->data_too_long_instead_value.'\' where id="'.$key.'"'; 
} 
$return = $this->execute($sql); 
if(!$return){ 
$this->initTable(); 
$return = $this->execute($sql,true); 
} 
return $return; 
} 
private function initTable(){ 
if($this->mysql_version>4){ 
$sql = " 
CREATE TABLE if not exists `".$this->storage_name."` ( 
`id` char(32) NOT NULL default 'ERR', 
`value` VARBINARY(".$this->max_session_data_length.") NULL, 
`time` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, 
PRIMARY KEY (`id`), 
KEY `time` (`time`) 
) ENGINE=MEMORY; 
"; 
}else{ 
$sqlSlow = " 
CREATE TABLE if not exists `".$this->storage_name."_slow` ( 
`id` char(32) NOT NULL default 'ERR', 
`value` text NULL, 
`time` int(10) not null default '0', 
PRIMARY KEY (`id`), 
KEY `time` (`time`) 
) ENGINE=MyISAM; 
"; 
$this->execute($sqlSlow,true); 
$sql = " 
CREATE TABLE if not exists `".$this->storage_name."` ( 
`id` char(32) NOT NULL default 'ERR', 
`value` VARCHAR(255) NULL, 
`time` int(10) not null default '0', 
PRIMARY KEY (`id`), 
KEY `time` (`time`) 
) ENGINE=MEMORY; 
"; 
} 
return $this->execute($sql,true); 
} 
private function execute($sql,$die=false) 
{ 
if($die) 
{ 
mysql_query($sql,$this->conn) or die("exe Sql error:<br>".mysql_error()."<br>".$sql."<hr>"); 
} 
else 
{ 
mysql_query($sql,$this->conn); 
if(mysql_error()){ 
return false; 
}else{ 
return true; 
} 
} 
} 
private function getOne($sql,$die=false){ 
$rs = $this->query($sql,$die); 
if($rs && ($one = mysql_fetch_row($rs)) ){ 
return $one[0]; 
}else{ 
return false; 
} 
} 
private function query($sql,$die=false){ 
if($die) 
$rs = mysql_query($sql,$this->conn) or die("query Sql error:<br>".mysql_error()."<br>".$sql."<hr>"); 
else 
$rs = mysql_query($sql,$this->conn); 
return $rs; 
} 
} 
$lnk = mysql_connect('localhost', 'root', '123456') 
or die ('Not connected : ' . mysql_error()); 
// make foo the current db 
mysql_select_db('test', $lnk) or die ('Can\'t use foo : ' . mysql_error()); 
$S = new session($lnk); 
if(!$S->last){ 
$S->last = time(); 
} 
echo "First visit at ".$S->last."<br>"; 
if(!$S->lastv){ 
$S->lastv = 0; 
} 
$S->lastv++; 
echo "lastv=".$S->lastv."<br>"; 
echo "test=".$S->test."<br>"; 
if(isset($_GET['max'])){ 
$S->boom = str_repeat("OK",255); 
} 
if(isset($_GET['boom'])){ 
$S->boom = $_GET['boom']; 
} 
echo "boom=".$S->boom."<br>"; 
?>
PHP 相关文章推荐
我的论坛源代码(二)
Oct 09 PHP
加强版phplib的DB类
Mar 31 PHP
php 代码优化的42条建议 推荐
Sep 25 PHP
PHP 变量的定义方法
Jan 26 PHP
PHP CLI模式下的多进程应用分析
Jun 03 PHP
php file_get_contents抓取Gzip网页乱码的三种解决方法
Nov 12 PHP
win7计划任务定时执行PHP脚本设置图解
May 09 PHP
PHP Streams(流)详细介绍及使用
May 12 PHP
Laravel框架模板加载,分配变量及简单路由功能示例
Jun 11 PHP
php微信公众号开发之微信企业付款给个人
Oct 04 PHP
laravel-admin 后台表格筛选设置默认的查询日期方法
Oct 03 PHP
PHP 技巧 * SVG 保存为图片(分享图生成)
Apr 02 PHP
PHP 加密/解密函数 dencrypt(动态密文,带压缩功能,支持中文)
Jan 30 #PHP
防止MySQL注入或HTML表单滥用的PHP程序
Jan 21 #PHP
php 动态多文件上传
Jan 18 #PHP
PHP $_SERVER详解
Jan 16 #PHP
php 删除数组元素
Jan 16 #PHP
php完全过滤HTML,JS,CSS等标签
Jan 16 #PHP
php array_flip() 删除数组重复元素
Jan 14 #PHP
You might like
php操作memcache缓存方法分享
2015/06/03 PHP
TP3.2批量上传文件或图片 同名冲突问题的解决方法
2017/08/01 PHP
Thinkphp自定义生成缩略图尺寸的方法
2019/08/05 PHP
PHP的重载使用魔术方法代码实例详解
2021/02/26 PHP
JavaScript随机排序(随即出牌)
2010/09/17 Javascript
jQuery UI的Dialog无法提交问题的解决方法
2011/01/11 Javascript
ASP.NET jQuery 实例18 通过使用jQuery validation插件校验DropDownList
2012/02/03 Javascript
javascript关于open.window子页面执行完成后刷新父页面的问题分析
2015/04/27 Javascript
javascript比较两个日期相差天数的方法
2015/07/23 Javascript
JS实现弹出浮动窗口(支持鼠标拖动和关闭)实例详解
2015/08/06 Javascript
详解js中==与===的区别
2017/01/08 Javascript
基于angular2 的 http服务封装的实例代码
2017/06/29 Javascript
jQuery实现html双向绑定功能示例
2017/10/09 jQuery
如何让Nodejs支持H5 History模式(connect-history-api-fallback源码分析)
2019/05/30 NodeJs
在layui中select更改后生效的方法
2019/09/05 Javascript
详解node.js 事件循环
2020/07/22 Javascript
python中执行shell命令的几个方法小结
2014/09/18 Python
Python实现的HMacMD5加密算法示例
2018/04/03 Python
python 识别图片中的文字信息方法
2018/05/10 Python
Python3利用print输出带颜色的彩色字体示例代码
2019/04/08 Python
python绘制BA无标度网络示例代码
2019/11/21 Python
html5中为audio标签增加停止按钮动作实现方法
2013/01/04 HTML / CSS
华为的Java面试题
2014/03/07 面试题
开业主持词
2014/03/21 职场文书
运动会口号16字
2014/06/07 职场文书
学校四群教育实施方案
2014/06/12 职场文书
向女朋友道歉的话
2015/01/20 职场文书
大国崛起日本观后感
2015/06/02 职场文书
男人帮观后感
2015/06/18 职场文书
党员证明信
2015/06/19 职场文书
《云雀的心愿》教学反思
2016/02/23 职场文书
优秀员工演讲稿
2019/06/21 职场文书
Sql-Server数据库单表查询 4.3实验课
2021/04/05 SQL Server
游戏《铁拳》动画化!2022年年内播出
2022/03/21 日漫
python 闭包函数详细介绍
2022/04/19 Python
python如何利用cv2.rectangle()绘制矩形框
2022/12/24 Python