用mysql内存表来代替php session的类
<?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>"; 
?>
