session相關儲存擴充

來源:互聯網
上載者:User

session相關儲存擴充

作者 三石  sanshi0815
mail sanshi0815@tom.com

對於session的儲存,現在解決方案很多,利用最近的時間,完善了,一下。並使用程式實現。
現在使用了一個session的工程類,來控制session的調用跟使用。當前實現的是mysql,
跟memcached的2中儲存方式,並解決了memcache擴充沒有安裝使用php程式調用的可能性。
所以我們先說下memcache的安裝問題。
首先下載 memcached 網站是 www.danga.com
解壓,然後安裝,如果提示缺少libevent 就到他提示的網站去下載安裝。
安裝完,在回頭安裝memcached,這個時候,如果安裝libevent的時候,指定了,安裝目錄,那麼這個時候會提示一個
so檔案找不到,但是去libevent 安裝目錄下,lib下面是有這個檔案的,這個時候,需要做個串連把這個缺少的檔案
串連到/usr/lib下也就是說,在系統的預設的載入庫中做個串連,讓memcache能夠找的到。
編譯完成,memcached也就安裝完成了,然後啟動memcached ,去memcached的bin目錄下執行,./memcache -h這個命令
如果正式運行就算是啟動完畢了,然後根據提示啟動memcached的服務
命令如下,請根據自己的實際情況修改 /usr/local/memcache/memcached -d -u root -m 64 -l 192.168.241.195 -p 11211

這個時候,memcached的伺服器就算安裝完成了

現在我們安裝php的擴充
網上有現成的,但是我安裝的是時候發現了一些問題。
使用phpize運行下
然後開始編譯php的載入模組
運行
解壓,進入運行
./configure --enable-memcache --with-php-config=/usr/local/bin/php-config --with-zlib-dir
這個時候提示php-config 找不到

大家要注意了 --with-php-config 這個參數,是要我們告訴他再剛開始編譯php的時候,把php放在了那個目錄下面
如果我們編譯php的時候指定了,就換成那個目錄,然後加上php-config 就行了,如果我們編譯php的時候,沒有指定的話,
那麼我們會麻煩些,我們不知道我們的php放在那個目錄下面了,那麼我們就去php源碼下,運行./configure -h這個命令,
看看php預設安裝在那裡了。
然後繼續運行 ./configure --enable-memcache --with-php-config=/usr/local/bin/php-config --with-zlib-dir 這個時候,
如果我們在編譯php目錄的話,還會提示一個錯誤,說php-session.h這個檔案找不到。這個地方,可就麻煩了,我看了下configure
這個指令碼,他裡面session_inc_path 這樣的一個變數,因為我們編譯php的時候沒有指定php的存放目錄,所以這個.h的檔案,不在
這個指令碼裡嘗試判斷的檔案中,所以我們要手動修改這個指令碼,在if完成後,加上一句
session_inc_path="/usr/local/include/php/ext/php_session.h"
當然,是你這個.h檔案一定存在的情況下。編譯完成,記住最後給你那個目錄,然後修改php.ini檔案,
修改so檔案的載入目錄,然後載入so模組,最後重新啟動你的apache,然後跑個測試程式如果成功,那麼恭喜你,你順利完成了,
memcache的全部安裝。

關於適用範圍,我們不多說了,因為現在我們做的這三種儲存,一個是檔案,一個資料庫,一個是memcache,
有著不同的使用範圍,這個需要個人去體會了。

現在開始說下程式,為了更加方便的使用這個session的不同的儲存機制,我做了一個session的工廠類,來降低耦合性,這樣對我們以後的擴充
會有很大的好處。

sessionFartory.class.php
[code]
<?php
/**    
 * base class
 * @version  1.0.0
 * @author   sanshi0815
 * @mail        sanshi0815@tom.com
 */
class sessionFartory
{
 function __construct($module_name="")
 {
  $this->sessionFartory($module_name);
 }
 function sessionFartory($module_name="")
 {
  //設定session的有效時間
  //$maxLife = get_cfg_var('session.gc_maxlifetime') ? get_cfg_var('session.gc_maxlifetime') : 1440;
  if($module_name=="mysql")
  {
   $this->setSessionObject($module_name);
  }else if($module_name=="memcache"){
   $this->setSessionObject($module_name);
  }else{
  }
  session_start();
 }
 function setSessionObject($module_name)
 {
  //設定sesion模組的名字
  //session_module_name(__CLASS__);
  $objectName = "{$module_name}Session";
  //通過工廠類取得
  include_once(dirname(__FILE__)."/factryObject.class.php");
  $sesionObject = factryObject::getClass($objectName);
  //設定執行的方法
  session_set_save_handler
  (
   array (& $sesionObject, "__open"),
   array (& $sesionObject, "__close"),
   array (& $sesionObject, "__read"),
   array (& $sesionObject, "__write"),
   array (& $sesionObject, "__destroy"),
   array (& $sesionObject, "__gc")
  );
 }

}
?>
[/code]
這段代碼並不麻煩,但是有一些潛在的規範

關於/**
  * 銷毀到期session
 */
 function __gc($maxlifetime)
這個方法,我在實際測試的過程中,沒有發現這個方法在什麼時候調用,如果有知道的請告訴我下

我們現在看看,mysql資料庫的儲存
mysqlSession.class.php
[code]
<?php
/**    
 * base class
 * @version  1.0.0
 * @author   sanshi0815
 * @mail        sanshi0815@tom.com
 */
include_once(dirname(__FILE__)."/adodbObject.class.php");
class mysqlSession extends adodbObject
{
 var $tableName = "session";
 var $sessionID = "session_id";
 var $tableF = array("session_data","expiry","last_time");
 var $dbConfigType = "";
 function mysqlSession()
 {
  //設定session的有效時間
  $this->maxLife = get_cfg_var('session.gc_maxlifetime') ? get_cfg_var('session.gc_maxlifetime') : 1440;
 }
 /**
  * 開啟session
 */
 function __open($save_path, $session_name)
 {
  $this->adodbObject($this->dbConfigType);
  return true;
 }
 /**
  * 關閉session
 */
 function __close()
 {
  return true;
 }
 /**
  * 讀取session
 */
 function __read($sessionID)
 {
  //$this->__gc($this->maxLife);
  //設定where條件
  $where = "{$this->tableF[1]} > '".time()."' AND {$this->sessionID}='{$sessionID}'";
  //取得資料
   $sql="SELECT * FROM {$this->tableName} WHERE ".$where;
  $sessionData = $this->select($sql);
  $sessionData = isset($sessionData[0])?$sessionData[0]:"";
  $curTime = time();
  $expiry = $curTime+$this->maxLife;
  //更新session操作時間
      $this->update(
    $this->tableName,
    array(
    $this->tableF[0]=>isset($sessionData[$this->tableF[0]])?$sessionData[$this->tableF[0]]:'',
       $this->tableF[1]=>$expiry,
       $this->tableF[2]=>$curTime
    ),
    $where);
  return isset($sessionData[$this->tableF[0]]) ? unserialize($sessionData[$this->tableF[0]]) : false;
 }
 /**
  * 寫入session
 */
 function __write($sessionID, $sessionData)
 {
  //設定where條件
  $where = "{$this->sessionID}='{$sessionID}'";
  //取得資料
  $sql="SELECT * FROM {$this->tableName} WHERE ".$where;
  $data = $this->select($sql);
  $curTime = time();
  $expiry = $curTime+$this->maxLife;
  if(empty($data))
  {
   //插入資料
   $this->insert(
    $this->tableName,
    array($this->sessionID=>$sessionID,$this->tableF[0]=>serialize($sessionData),$this->tableF[1]=>$expiry,$this->tableF[2]=>$curTime)
       );
  }else{
   //更新資料
   $this->update(
     $this->tableName,
     array($this->tableF[0]=>serialize($sessionData),$this->tableF[1]=>$expiry,$this->tableF[2]=>$curTime),
     $where);
  }
 }
 /**
  * 登出session
 */
 function __destroy($sessionID)
 {
  $where = "{$this->sessionID}='{$sessionID}'";
  $del = $this->delete($this->tableName,$where);
  return $del==1 ? true : false;
 }
 /**
  * 銷毀到期session
 */
 function __gc($maxlifetime)
 {
  $where = "{$this->tableF[1]} <= '".time()."'";
  return $this->delete($this->tableName,$where);
 }
}
?>
[/code]
下面是對應的sql語句
[code]
CREATE TABLE `session` (
  `session_id` varchar(32) NOT NULL,
  `session_data` mediumtext NOT NULL,
  `expiry` varchar(100) NOT NULL,
  `last_time` varchar(100) NOT NULL,
  KEY `session_id` (`session_id`),
  KEY `expiry` (`expiry`),
  KEY `last_time` (`last_time`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
[/code]

這裡是可以擴充的,要去修改對應的方法裡的設定。
這個也是靈活性,最強的,比如再線統計等等,都能實現

下面是memcache的這個跟php本身的那個檔案儲存體差不多,不可排序,等等,功能都不能實現
memcacheSession.class.php
[code]
<?php
/**    
 * base class
 * @version  1.0.0
 * @author   sanshi0815
 * @mail        sanshi0815@tom.com
 */
include_once(dirname(__FILE__)."/memcacheObject.class.php");
class memcacheSession extends memcacheObject
{
 function memcacheSession()
 {
  //設定session的有效時間
  $this->maxLife = get_cfg_var('session.gc_maxlifetime') ? get_cfg_var('session.gc_maxlifetime') : 1440;
 }
 function __open($save_path, $session_name)
 {
  $this->memcacheObject();
  return true;
 }
 function __close()
 {
  $this->close();
  return true;
 }
 /**
  * 讀取session
 */
 function __read($sessionID)
 {
  $data = $this->get($sessionID);
  if(is_array($data))
   $this->update($sessionID,$data,$this->maxLife);
  return $data;
 }
 /**
  * 寫入session
 */
 function __write($sessionID, $sessionData)
 {
  return $this->set($sessionID,$sessionData,$this->maxLife);
 }
 /**
  * 登出session
 */
 function __destroy($sessionID)
 {
  return $this->delete($sessionID);
 }
 /**
  * 銷毀到期session
 */
 function __gc($sessionID)
 {
  return true;
 }
}
?>
[/code]
關於memcache的非擴充也擴充的相容性是在 memcacheObject 裡做的
現在我們看下
memcacheObject.class.php
[code]
<?php
/**    
 * base class
 * @version  1.0.0
 * @author   sanshi0815
 * @mail        sanshi0815@tom.com
 */
class memcacheObject
{
 var $flag=0;
 var $mObject="";
 var $isPhp;
 function memcacheObject()
 {
  $this->isPhp = class_exists("Memcache");
  if(!$this->isPhp)
  {
   include_once("MemCachedClient.class.php");
  }
  return $this->connect();
 }
 function connect()
 {
  global $memcacheConfig;
  if($this->isPhp)
  {
   $this->mObject = new Memcache();
   $this->mObject->addServer($memcacheConfig['server'],$memcacheConfig['port']);
   //$this->mObject->connect($memcacheConfig['server'],$memcacheConfig['port']) or die("Could not connect memcache server!");
  }else{
   $options["servers"]=array("{$memcacheConfig['server']}:{$memcacheConfig['port']}");
   $options["debug"]=false;
   $this->mObject = new MemCachedClient($options);
  }
  
 }
 function set($key,$value,$maxLeft=0)
 {
  is_object($this->mObject) or $this->connect();
  return $this->mObject->set($key,$value,$this->flag,$maxLeft) ? true : false;//die("memcache set valuse is failed");
 }
 function get($key)
 {
  is_object($this->mObject) or $this->connect();
  return $this->mObject->get($key);
 }
 function update($key,$value,$maxLeft=0)
 {
  is_object($this->mObject) or $this->connect();
  return $this->mObject->replace($key,$value,$this->flag,$maxLeft) ? true : false;//die("memcache update valuse is failed");
 }
 function delete($key)
 {
  is_object($this->mObject) or $this->connect();
  return $this->mObject->delete($key,10)  ? true : false;//die("memcache delete valuse is failed");
 }
 function close()
 {
  is_object($this->mObject) or $this->connect();
  $this->mObject->close();
 }
}
?>
[/code]

現在我們看下測試程式
現在看一個發送session的
[code]
<?php
/**    
 * base class
 * @version  1.0.0
 * @author   sanshi0815
 * @mail        sanshi0815@tom.com
 */
include_once("config/config.inc.php");
include_once("classes/sessionFartory.class.php");
new sessionFartory('memcache');
//new sessionFartory('mysql');
echo $_SESSION['time'] = array("a",'b');
?>
[/code]
這是一個接受並登出的測試
[code]
<?php
/**    
 * base class
 * @version  1.0.0
 * @author   sanshi0815
 * @mail        sanshi0815@tom.com
 */
include_once("config/config.inc.php");
include_once("classes/sessionFartory.class.php");
new sessionFartory('memcache');
//new sessionFartory('mysql');
print_r($_SESSION);
session_destroy();
print_r($_SESSION);
?>
[/code]

作者 三石  sanshi0815
mail sanshi0815@tom.com
轉載請著名作者!並說明出處

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.