复制代码 代码如下: <?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);