用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 相关文章推荐
php 分页函数multi() discuz
Jun 21 PHP
在PHP中操作Excel实例代码
Apr 29 PHP
用sql命令修改数据表中的一个字段为非空(not null)的语句
Jun 04 PHP
php实现统计目录文件大小的函数
Dec 25 PHP
PHP的Laravel框架中使用消息队列queue及异步队列的方法
Mar 21 PHP
PHP封装的数据库保存session功能类
Jul 11 PHP
iOS自定义提示弹出框实现类似UIAlertView的效果
Nov 16 PHP
关于ThinkPHP中的异常处理详解
May 11 PHP
PHP命名空间namespace及use的简单用法分析
Aug 03 PHP
用Laravel Sms实现laravel短信验证码的发送的实现
Nov 29 PHP
php实现的表单验证类完整示例
Aug 13 PHP
laravel-admin表单提交隐藏一些数据,回调时获取数据的方法
Oct 08 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 explode()函数用法、切分字符串
2012/10/03 PHP
php利用单例模式实现日志处理类库
2014/02/10 PHP
PHP的Yii框架中使用数据库的配置和SQL操作实例教程
2016/03/17 PHP
PHP实现的登录,注册及密码修改功能分析
2016/11/25 PHP
动态为事件添加js代码示例
2009/02/15 Javascript
mailto的使用技巧分享
2012/12/21 Javascript
jquery动态增加删除表格行的小例子
2013/11/14 Javascript
Javascript排序算法之计数排序的实例
2014/04/05 Javascript
JavaScript获取元素尺寸和大小操作总结
2015/02/27 Javascript
freemarker判断对象是否为空的方法
2015/08/13 Javascript
学习JavaScript设计模式(接口)
2015/11/26 Javascript
jquery自定义插件开发之window的实现过程
2016/05/06 Javascript
jQuery EasyUI 为Combo,Combobox添加清除值功能的实例
2017/04/13 jQuery
nodejs基于mssql模块连接sqlserver数据库的简单封装操作示例
2018/01/05 NodeJs
vue.extend与vue.component的区别和联系
2018/09/19 Javascript
nodejs中使用worker_threads来创建新的线程的方法
2021/01/22 NodeJs
查看django执行的sql语句及消耗时间的两种方法
2018/05/29 Python
Pycharm无法使用已经安装Selenium的解决方法
2018/10/13 Python
Python装饰器简单用法实例小结
2018/12/03 Python
python设置环境变量的原因和方法
2019/06/24 Python
Python如何优雅获取本机IP方法
2019/11/10 Python
妙用itchat! python实现久坐提醒功能
2019/11/25 Python
pytorch中nn.Conv1d的用法详解
2019/12/31 Python
tensorflow模型继续训练 fineturn实例
2020/01/21 Python
解决selenium+Headless Chrome实现不弹出浏览器自动化登录的问题
2021/01/09 Python
中国最大的团购网站:聚划算
2016/09/21 全球购物
德国化妆品和天然化妆品网上商店:kosmetikfuchs.de
2017/06/09 全球购物
Java如何调用外部Exe程序
2015/07/04 面试题
《陈涉世家》教学反思
2014/04/12 职场文书
助人为乐好少年事迹材料
2014/08/18 职场文书
2014年药店工作总结
2014/11/20 职场文书
2015年个人招商工作总结
2015/04/25 职场文书
现货白银电话营销话术
2015/05/29 职场文书
2016大学军训心得体会
2016/01/11 职场文书
python实现简单的井字棋
2021/05/26 Python
详解如何用Python实现感知器算法
2021/06/18 Python