-
-
/**
- * session mysql 內存表
- @Usage: 使用其他儲存方法(mysql 或 memcache)取代 php sessoin
- @author:lein
- @Version:1.2
- */
- session_start();
- if(!isset($_SESSION['testsession_start();
- if(!isset($_SESSION['testses'' ])){
- $_SESSION['test']="123_lein_".date("Y-m-d H:i:s");
- }
-
- class session{
- //會話資料
- private $data;
- //引擎,mysql或memcache
- private $engine;
- //php 會話過期時間
- private $sessionexpiredTime;
- 當前使用者的會話 // cookie值
- private $sessionID;
- //會話苦力名稱
- private $sessionCookieName;
- public function session($engineBase=NULL,$engineName='mysql',$storage_name='php_session') {
- try{
- $this->sessionexpiredTime = intval(ini_get("session.cache_expire) "))*10;//預設是180分鐘,太長了,改為了30分鐘
- }catch (Exception $Exception){
- $this->sessionexpiredTime = 1200;
- }
- 嘗試{
- $this->sessionCookieName = ini_get("session.name");
- }catch( Exception $Exception){
- $this->sessionCookieName = 'PHPSESSID';
- }
-
- if(!isset($_COOKIE[$this->sessionCookieName])){
- @session_start ();
- $this->sessionID=session_id();
- }else{
- $this->sessionID=$_COOKIE[$this->sessionCookieName];
- }
- $className = $engineName."SessionEngine";
- $this->engine = new $className(
- array(
- 'storage_name'=>$storage_name,//儲存資料的mysql表名或memcahce鍵;
- 'expire_time'= >$this->sessionexpiredTime,
- 'data_too_long_instead_value' => '{__DATA IS *$* TO LONG__}'
- ),
- $this->sessionID,
- $engineBase
- );
- $this->init();
- $this->loadFromSession();
- $this->engine->refresh();
- $this-> engine->cleanup();
- }
- 私有函數init()
- {
- $this->data = $this->engine->get();
- if(empty( $this->data)){
- @session_start();
- if(!empty($_SESSION)){
- $this->data = $_SESSION;
- $this->engine- >create(false, $this->data);
- }
- else
- {
- $this->engine->create(false, "");
- }
- }
- }
- public function loadFromSession($flagStartSession = false){
- $flag=false;
- if($flagStartSession){
- @session_start(); ($_SESSION&&is_array($_SESSION)){
- foreach($_SESSION as $k=>$v){
- if(!isset($this->data[$ k])){
- $this ->data[$k] = $v;
- $flag=true;
- }
- }
- }
- if($flag){
- $this->engine-> set(false, $this->data);
- }
- }
- 私有函數__get($nm)
- {
- if (isset($this->data[$nm] )) {
- $r = $this -> 資料[$nm];
- 回傳$r;
- }
- else
- {
- 回傳NULL;
- }
- }
- 私有函數__set($nm, $val)
- {
- $this->data[$nm] = $val;
- $this->engine->set(false, $this->data);
- }
-
- 私有函數__isset($nm)
- {
- return isset($this->data[$nm]);
- }
-
- 私有函數__unset($nm)
- {
- unset($this->data[$nm]);
- $this->engine->set(false, $this ->data);
- }
-
- function __destruct(){
- $this->data = NULL;
- $this->engine->close();
- $this ->engine = NULL;
- }
- }
-
- 介面SessionEngine
- {
- /*
- * 設定變數
- * @param $arr array,array(變數名稱=>變數值,...)
- * /
- public function setVariable($arr);
- /*
- * 取得會話值
- * @param $key string
- */
- public function get($key="" );
- /*
- * 設定會話值
- * @param $key 字串
- * @param $value 字串
- */
- public function set($key=" ",$value =“”);
- /*
- * 設定會話值
- * @param $key 字串
- * @param $value 字串
- */
- public function create($key="",$value =");
- /*
- * 更新會話的無效時間
- * @param $key string
- */
- public function refresh ($key="");
- /*
- * 關閉mysql 或memcache 連線
- */
- public function close();
- /*
- * 刪除過期會話
- */
- public function cleanup();
- }
-
- 最終類別mysqlSessionEngine 實作SessionEngine{
- private $id="";
- private $storage_name='_session'; 🎜> private $storage_name_slow='php_session_slow';
- private $data_too_long_instead_value = '{__DATA IS ~ TO LONG__}';//如果資料長於$max_session_data_length 是此版本插入到內存表中。
- 私人$expire_time=1200;
- 私人$max_session_data_length = 2048;
- 私人$conn;
- 私人$mysql_version;
- public function my="SarraionEngine($mysql=$ ",&$_conn){
- $this->setVariable($arr);
- $this->id = $key;
- if(empty($this->id)||strlen($ this->id)!=32){
- throw new Exception(__FILE__."->".__LINE__.": 會話的cookie 名稱不能為空,且必須只有32 個字元!");
- }
- $this->conn = $_conn;
- if(!$this->conn||!is_resource($this->conn)){
- throw new Exception(__FILE__."->". __LINE__.": 需要mysql 連線!」);
- }
- $this->mysql_version = $this->getOne(" 選取樓層(version())");
- if($this-> mysql_version $this->max_session_data_length = 255;
- }
- }
- public function setVariable($arr){
- if(!empty($arr)&arr_x )){
- 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('從'.$this->storage_name.' 中選取值,其中id="'.$key .'"');
- if($return==$this->data_too_long_instead_value)
- {
- $return = $this->getOne(' 從'.$this->storage_name_slow.' 中選擇值。 ' 其中id= "'.$key.'"');
- }
- if(!$return)
- {
- $mysqlError = mysql_error($this->conn);
- if(strpos($mysqlError,"不存在")!==false)
- {
- $this->initTable();
- }
- $return = array();
- }
- else
- {
- $return = unserialize($return);
- }
- 回傳$return;
- }
- public function close(){
- }
- public function close(){
- $this->conn);
- }
- public function cleanup(){
- if($this->mysql_version>4){
- $sql = '從'.$this->storage_name 中刪除。 '其中 date_add(`time`,INTERVAL '.$this->expire_time.' SECOND) }else{
- $sql = '從 '.$this->storage_name_slow 中刪除。 '其中`time`+'.$this->expire_time.' if($_SESSION['username']=="leinchu"){
- echo $sql;
- }
- $this->execute($sql);
- $sql = '從'.$this->storage_name 移除。 '其中`time`+'.$this->expire_time.' if($_SESSION['username']=="leinchu"){
- echo $sql;
- }
- }
- $this->execute($sql); }
- public function refresh($key=""){
- if($this->mysql_version>4){
- $sql = 'update '.$this->storage_name.' 設定 `time`= CURRENT_TIMESTAMP() 其中id="'.$key.'"';
- }else{
- $sql = '更新 '.$this->storage_name.' 設定 `time`=unix_timestamp() where id="'.$key.'"';
- }
- $return = $this->execute($sql);
- if(!$return){
- $this->initTable();
- $return = $this->execute($sql,true);
- }
- 回傳 $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)
- {
- if($this->mysql_version>4){
- 拋出新的例外(__FILE__."-> ; ". __LINE__.": 會話資料長度超過最大允許長度(".$this->max_session_data_length.")!");
- }
- }
- if($this->mysql_version>4){
- $sql = '替換為'.$this->storage_name.'設定 value=/''.$value。 '/',id="'.$key.'",`time`=CURRENT_TIMESTAMP()';
- }else{
- $sql = '替換為'.$this->storage_name。時間`=unix_timestamp()';
- }
- $return = $this->execute($sql);
- if(!$return){
- $this->initTable();
- $return = $this->execute($sql,true);
- }
- 回傳 $return;
- }
- public function set($key="",$value=""){
- if($key=="") $key = $this->id;
- if($value != "") $value = mysql_real_escape_string(serialize($value),$this->conn);
- $sql = '更新'.$this->storage_name.'設定 value=/''.$value.'/' where id="'.$key.'"';
- if(strlen($value)>$this->max_session_data_length)
- {
- if($this->mysql_version>4){
- 拋出新的例外(__FILE__."-> ; ". __LINE__.": 會話資料長度超過最大允許長度(".$this->max_session_data_length.")!");
- }
- $sql = '替換為'.$this->storage_name_slow。 =unix_timestamp()';
- $this->execute($sql,true);
- $sql = '更新'.$this->儲存名稱。 '設定 value=/''.$this->data_too_long_instead_value.'/' 其中 id="'.$key.'"';
- }
- $return = $this->execute($sql);
- if(!$return){
- $this->initTable();
- $return = $this->execute($sql,true);
- }
- 回傳 $return;
- }
- private function initTable(){
- if($this->mysql_version>4){
- $sql = "
- 如果不存在則建立表格 `".$this-> "` (
- `id` char(32) NOT NULL 預設'ERR',
- `value` VARBINARY(".$this->max_session_data_length.") NULL,
- `time`CURRENT_TIMESTAMP 時的計時器不為NULL 預設CURRENT_TIMESTAMP,
- PRIMARY KEY (`id`),
- KEY `time` (`time`)
- ) ENGINE=MEMORY> ";
- }else{
- $sqlSlow = "
- 如果不存在則建立表格 `".$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 = "
- 如果不存在則建立表格 `".$this->storage_name."` (
- `id` char(32) NOT NULL 預設 'ERR',
- `value` VARCHAR(255) NULL,
- `time` int(10) not null default '0',
- PRIMARY KEY (`id`),
- KEY `time` (`time`)
- ) 引擎=記憶體;
- }
- return $this->execute($sql,true);
- }
- 初始函數execute($sql,$die=false)
- {
- if($die)
- {
- mysql_query($sql,$this->conn) or die(" exeor Sql 錯誤:
".mysql_error()." ".$sql." ");
- }
- else
- {
- mysql_query($sql,$this->conn);
- if(mysql_error()){
- return false;
- }else{
- 回傳 true;
- }
- }
- }
- private function getOne($sql,$die=false){
- $rs = $this->查詢($sql,$die);
- if($rs && ($one = mysql_fetch_row($rs)) ){
- return $one[0];
- }else{
- 回傳 false;
- }
- }
- 乾燥函數查詢($sql,$die=false){
- if($die)
- $rs = mysql_query($sql,$this->conn) or die("查詢Sql錯誤:
".mysql_error()." ".$sql." ");
- else
- $rs = mysql_query($sql,$this->conn);
- 回傳 $rs;
- }
- }
- $lnk = mysql_connect('localhost', 'root', '123456')
- 或 die ('未連線: ' .mysql_error());
-
- // 使 foo 成為目前資料庫
- mysql_select_db('test', $lnk) 或 die ('Can/'t use foo : ' . mysql_error());
- $S = 新會話($lnk);
- if(!$S->last){
- $S->last = time();
- }
- echo "第一次造訪於 ".$S->last."
";
- if(!$S->lastv){
- $S->lastv = 0;
- }
- $S->lastv++;
- echo "lastv=".$S->lastv."
";
- echo "test=".$S->test."
";
- if(isset($_GET['max'])){
- $S->boom = str_repeat("OK",255);
- }
- if(isset($_GET['boom'])){
- $S->boom = $_GET['boom'];
- }
- echo "boom=".$S->boom."
";
- ?
|