用mysql内存表来代替php session的类
2018-09-07 19:15
复制代码 代码如下:
<?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 users 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 sessions 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__.: Sessions cookie name cant 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,doesnt 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>;
?>