PHP實現多伺服器session共享之memcache共享

科技小先鋒發表於2017-11-17
接下來,再自定義一套session處理機制,關於session的實現方法我就不再多講,直接貼程式了。
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
//===========================================
// 程式:   Memcache-Based Session Class
// 功能:   基於Memcache儲存的 Session 功能類
// 作者:    yejr
// 網站:    http://imysql.cn
// 時間:    2007-01-05
//===========================================
/**
 * 檔案:    MemcacheSession.inc.php
 * 類名:    MemcacheSession Class
 * 功能:    自主實現基於Memcache儲存的 Session 功能
 * 描述:    這個類就是實現Session的功能,基本上是通過
 *          設定客戶端的Cookie來儲存SessionID,
 *          然後把使用者的資料儲存在伺服器端,最後通過
 *          Cookie中的Session Id來確定一個資料是否是使用者的,
 *          然後進行相應的資料操作
 *
 *          本方式適合Memcache記憶體方式儲存Session資料的方式,
 *          同時如果構建分散式的Memcache伺服器,
 *          能夠儲存相當多快取資料,並且適合使用者量比較多併發比較大的情況
 *
 * 注意: 本類必須要求PHP安裝了Memcache擴充套件或者必須有Memcache的PHP API
 *       獲取Memcache擴充套件請訪問: http://pecl.php.net
 */
//設定 SESSION 有效時間,單位是 秒
define(`SESS_LIFTTIME`, 3600);
//定義memcache配置資訊
define(`MEMCACHE_HOST`, `localhost`);
define(`MEMCACHE_PORT`, `10000`);
if (!defined(`MemcacheSession`))
{
    define(`MemcacheSession`,    TRUE);
class MemacheSession
{
    // {{{ 類成員屬性定義
    static  $mSessSavePath;
    static  $mSessName;
    static  $mMemcacheObj;
    // }}}
    // {{{ 初始化建構函式
    /**
     * 建構函式
     *
     * @param string $login_user    登入使用者
     * @param int $login_type       使用者型別
     * @param string $login_sess    登入Session值
     * @return Esession
     */
    public function __construct()
    {
        //我的memcache是以php模組的方式編譯進去的,可以直接呼叫
        //如果沒有,就請自己包含 Memcache-client.php 檔案
        if (!class_exists(`Memcache`) || !function_exists(`memcache_connect`))
        {
            die(`Fatal Error:Can not load Memcache extension!`);
        }
        if (!empty(self::$mMemcacheObj) && is_object(self::$mMemcacheObj))
        {
            return false;
        }
        self::$mMemcacheObj = new Memcache;
        if (!self::$mMemcacheObj->connect(MEMCACHE_HOST , MEMCACHE_PORT))
        {
            die(`Fatal Error: Can not connect to memcache host `. MEMCACHE_HOST .`:`. MEMCACHE_PORT);
        }
        return TRUE;
    }
    // }}}
    /** {{{ sessOpen($pSavePath, $name)
     *
     * @param   String  $pSavePath
     * @param   String  $pSessName
     *
     * @return  Bool    TRUE/FALSE
     */
    public function sessOpen($pSavePath = ``, $pSessName = ``)
    {
        self::$mSessSavePath    = $pSavePath;
        self::$mSessName        = $pSessName;
        return TRUE;
    }
    // }}}
    /** {{{ sessClose()
     *
     * @param   NULL
     *
     * @return  Bool    TRUE/FALSE
     */
    public function sessClose()
    {
        return TRUE;
    }
    // }}}
    /** {{{ sessRead($wSessId)
     *
     * @param   String  $wSessId
     *
     * @return  Bool    TRUE/FALSE
     */
    public function sessRead($wSessId = ``)
    {
        $wData = self::$mMemcacheObj->get($wSessId);
        //先讀資料,如果沒有,就初始化一個
        if (!empty($wData))
        {
            return $wData;
        }
        else
        {
            //初始化一條空記錄
            $ret = self::$mMemcacheObj->set($wSessId, ``, 0, SESS_LIFTTIME);
            if (TRUE != $ret)
            {
                die("Fatal Error: Session ID $wSessId init failed!");
                return FALSE;
            }
            return TRUE;
        }
    }
    // }}}
    /** {{{ sessWrite($wSessId, $wData)
     *
     * @param   String  $wSessId
     * @param   String  $wData
     *
     * @return  Bool    TRUE/FALSE
     */
    public function sessWrite($wSessId = ``, $wData = ``)
    {
        $ret = self::$mMemcacheObj->replace($wSessId, $wData, 0, SESS_LIFTTIME);
        if (TRUE != $ret)
        {
            die("Fatal Error: SessionID $wSessId Save data failed!");
            return FALSE;
        }
        return TRUE;
    }
    // }}}
    /** {{{ sessDestroy($wSessId)
     *
     * @param   String  $wSessId
     *
     * @return  Bool    TRUE/FALSE
     */
    public function sessDestroy($wSessId = ``)
    {
        self::sessWrite($wSessId);
        return FALSE;
    }
    // }}}
    /** {{{ sessGc()
     *
     * @param   NULL
     *
     * @return  Bool    TRUE/FALSE
     */
    public function sessGc()
    {
        //無需額外回收,memcache有自己的過期回收機制
        return TRUE;
    }
    // }}}
    /** {{{ initSess()
     *
     * @param   NULL
     *
     * @return  Bool    TRUE/FALSE
     */
    public function initSess()
    {
        $domain = `.imysql.cn`;
        //不使用 GET/POST 變數方式
        ini_set(`session.use_trans_sid`,    0);
        //設定垃圾回收最大生存時間
        ini_set(`session.gc_maxlifetime`,   SESS_LIFTTIME);
        //使用 COOKIE 儲存 SESSION ID 的方式
        ini_set(`session.use_cookies`,      1);
        ini_set(`session.cookie_path`,      `/`);
        //多主機共享儲存 SESSION ID 的 COOKIE
        ini_set(`session.cookie_domain`,    $domain);
        //將 session.save_handler 設定為 user,而不是預設的 files
        session_module_name(`user`);
        //定義 SESSION 各項操作所對應的方法名:
        session_set_save_handler(
                array(`MemacheSession`, `sessOpen`),   //對應於靜態方法 My_Sess::open(),下同。
                array(`MemacheSession`, `sessClose`),
                array(`MemacheSession`, `sessRead`),
                array(`MemacheSession`, `sessWrite`),
                array(`MemacheSession`, `sessDestroy`),
                array(`MemacheSession`, `sessGc`)
                );
        session_start();
        return TRUE;
    }
    // }}}
}//end class
}//end define
$memSess    = new MemacheSession;
$memSess->initSess();
?>
  然後,在專案程式的標頭檔案中直接包含 MemacheSession.inc.php 即可,並且以前的程式不用做任何改動。
備註:memcache PECL 未來版本中,可以直接設定 php.ini 來這定自己的 session.save_handler,大致如下:
session.save_handler = memcache
session.save_path = "tcp://host:port?persistent=1&weight=2&timeout=2&retry_interval=15,tcp://host2:port2"
本文轉自葉金榮51CTO部落格,原文連結:http://blog.51cto.com/imysql/310478,如需轉載請自行聯絡原作者


相關文章