用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 相关文章推荐
dedecms采集中可以过滤多行代码的正则表达式
Mar 17 PHP
php之字符串变相相减的代码
Mar 19 PHP
计算php页面运行时间的函数介绍
Jul 01 PHP
php while循环得到循环次数
Oct 26 PHP
php将字符串转化成date存入数据库的两种方式
Apr 28 PHP
php实现获取文章内容第一张图片的方法
Nov 04 PHP
php利用imagemagick实现复古老照片效果实例
Feb 16 PHP
Laravel实现定时任务的示例代码
Aug 10 PHP
PDO操作MySQL的基础教程(推荐)
Aug 18 PHP
php 读写json文件及修改json的方法
Mar 07 PHP
PHP的mysqli_sqlstate()函数讲解
Jan 23 PHP
用php定义一个数组最简单的方法
Oct 04 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
层叠菜单的动态生成
2006/10/09 PHP
小文件php+SQLite存储方案
2010/09/04 PHP
超小PHP小马小结(方便查找后门的朋友)
2012/05/05 PHP
php实现json编码的方法
2015/07/30 PHP
PHP使用内置函数生成图片的方法详解
2016/05/09 PHP
PHP面向对象程序设计高级特性详解(接口,继承,抽象类,析构,克隆等)
2016/12/02 PHP
php实现等比例压缩图片
2018/07/26 PHP
Laravel核心解读之异常处理的实践过程
2019/02/24 PHP
jQuery使用手册之一
2007/03/24 Javascript
JS中令人发指的valueOf方法介绍
2013/02/22 Javascript
javascript判断非数字的简单例子
2013/07/18 Javascript
一个jquery实现的不错的多行文字图片滚动效果
2014/09/28 Javascript
浅谈Javascript 数组与字典
2015/01/29 Javascript
jQuery简单入门示例之用户校验demo示例
2016/07/09 Javascript
简单的js表格操作
2016/09/24 Javascript
jquery 动态增加,减少input表单的简单方法(必看)
2016/10/12 Javascript
javascript使用递归算法求两个数字组合功能示例
2017/01/03 Javascript
jQuery.Form上传文件操作
2017/02/05 Javascript
webpack4.0+vue2.0利用批处理生成前端单页或多页应用的方法
2019/06/28 Javascript
html+jQuery实现拖动滑块图片拼图验证码插件【移动端适用】
2019/09/10 jQuery
layer弹出层取消遮罩的方法
2019/09/25 Javascript
react实现移动端下拉菜单的示例代码
2020/01/16 Javascript
python批量修改文件名的实现代码
2014/09/01 Python
在Python中用get()方法获取字典键值的教程
2015/05/21 Python
Python中标准模块importlib详解
2017/04/16 Python
将Django项目部署到CentOs服务器中
2018/10/18 Python
在pycharm中显示python画的图方法
2019/08/31 Python
python+django+selenium搭建简易自动化测试
2020/08/19 Python
python实现马丁策略回测3000只股票的实例代码
2021/01/22 Python
HTML5 embed标签定义和用法详解
2014/05/09 HTML / CSS
丽笙酒店官方网站:Radisson Hotels
2019/05/07 全球购物
网上开商店的创业计划书
2014/01/19 职场文书
女儿满月酒致辞
2015/07/29 职场文书
《思路决定出路》读后感3篇
2019/12/11 职场文书
Echarts如何重新渲染实例详解
2022/05/30 Javascript
Vue router配置与使用分析讲解
2022/12/24 Vue.js