PHP SESSION 自定義會話管理器

前言

在遇到了 SESSION 混亂的問題后残腌,突然對自定義會話管理器有了興趣村斟,于是便研究實現(xiàn)了一番。

分析

根據(jù)PHP官網(wǎng)的說明抛猫,實現(xiàn)方式有兩種蟆盹,這里準(zhǔn)備用繼承類的方式做,同時將 SESSION 存儲于 Memcache 中闺金。

實現(xiàn)

首先先要寫一個繼承于 SessionHandlerInterface 的類逾滥。

class MemcachedHanlder implements SessionHandlerInterface
{
}

MemcachedHanlder 類實例化的時候,附上需要連接 Memcached 的參數(shù)败匹。

protected $_options;
protected $_memcached;
protected $_prefix;

function __construct(array $options = [])
{
    if (!isset($options['host'])) {
        $options['host'] = '127.0.0.1';
    }
    if (!isset($options['port'])) {
        $options['port'] = 11211;
    }
    if (!isset($options['persistent'])) {
        $options['persistent'] = false;
    }
    if (!isset($options['lifetime'])) {
        $options['lifetime'] = null;
    }
    $this->_prefix = isset($options['prefix']) ? $options['prefix'] : '';
    $this->_options = $options;
}

繼承 SessionHandlerInterface 的類需要實現(xiàn)幾個方法:open寨昙、closeread掀亩、write舔哪、destorygc

open 中連接 Memcached槽棍。

/**
 * Create new session, or re-initialize existing session
 * 
 * @param  string $path
 * @param  string $name
 * @return boolean
 */
public function open($path, $name)
{
    $options = $this->_options;
    if ($options) {
        $this->_memcached = new \Memcached($options);
        $this->_memcached->addServer($options['host'], $options['port'], $options['persistent']);
        return true;
    }
    return false;
}

/**
 * Closes the current session
 * 
 * @return integer
 */
public function close()
{
    return true;
}

/**
 * Read session data
 * 
 * @param  string $id
 * @return string
 */
public function read($id)
{
    return $this->_memcached->get($this->_prefix . $id, $this->_lifetime);
}

/**
 * Read session data
 * 
 * @param  string $id
 * @param  string $data
 * @return boolean
 */
public function write($id, $data)
{
    return $this->_memcached->set($this->_prefix . $id, $data, $this->_lifetime);
}

/**
 * Destroys a session
 * 
 * @param  string $id
 * @return boolean
 */
public function destroy($id)
{
    if (!$id && $this->_memcached->exists($this->_prefix . $id)) {
        return $this->_memcached->delete($this->_prefix . $id);
    }
    return true;
}

/**
 * Cleans up expired sessions
 * 
 * @param  string $value
 * @return boolean
 */
public function gc($maxlifetime)
{
    return true;
}

Handler 類寫完之后捉蚤,實例化它,并調(diào)用 session_set_save_handler 完成注冊炼七。

$options = [];
$handler = new MemcachedHanlder($options);
session_set_save_handler($handler, true);

這時候缆巧,開始暢享 SESSION 吧。

完整代碼

class MemcachedHanlder implements SessionHandlerInterface
{
    protected $_options;
    protected $_memcached;
    protected $_prefix;

    function __construct(array $options = [])
    {
        if (!isset($options['host'])) {
            $options['host'] = '127.0.0.1';
        }
        if (!isset($options['port'])) {
            $options['port'] = 11211;
        }
        if (!isset($options['persistent'])) {
            $options['persistent'] = false;
        }
        if (!isset($options['lifetime'])) {
            $options['lifetime'] = null;
        }
        $this->_prefix = isset($options['prefix']) ? $options['prefix'] : '';
        $this->_options = $options;
    }

    /**
     * Create new session, or re-initialize existing session
     * 
     * @param  string $path
     * @param  string $name
     * @return boolean
     */
    public function open($path, $name)
    {
        $options = $this->_options;
        if ($options) {
            $this->_memcached = new \Memcached($options);
            $this->_memcached->addServer($options['host'], $options['port'], $options['persistent']);
            return true;
        }
        return false;
    }

    /**
     * Closes the current session
     * 
     * @return integer
     */
    public function close()
    {
        return true;
    }

    /**
     * Read session data
     * 
     * @param  string $id
     * @return string
     */
    public function read($id)
    {
        return $this->_memcached->get($this->_prefix . $id, $this->_lifetime);
    }

    /**
     * Read session data
     * 
     * @param  string $id
     * @param  string $data
     * @return boolean
     */
    public function write($id, $data)
    {
        return $this->_memcached->set($this->_prefix . $id, $data, $this->_lifetime);
    }

    /**
     * Destroys a session
     * 
     * @param  string $id
     * @return boolean
     */
    public function destroy($id)
    {
        if (!$id && $this->_memcached->exists($this->_prefix . $id)) {
            return $this->_memcached->delete($this->_prefix . $id);
        }
        return true;
    }

    /**
     * Cleans up expired sessions
     * 
     * @param  string $value
     * @return boolean
     */
    public function gc($maxlifetime)
    {
        return true;
    }
}
$options = [];
$handler = new MemcachedHanlder($options);
session_set_save_handler($handler, true);

總結(jié)

記得之前面試的時候豌拙,有人問過我 SESSIONCOOKIE 之間的關(guān)系陕悬,SESSION 是怎么實現(xiàn)的,SESSION 除了存文件之外姆蘸,還能夠存在哪里墩莫,如何實現(xiàn)。

當(dāng)初的我都沒有回答上逞敷,想象當(dāng)初真的是太年輕了狂秦,也很天真。越接觸推捐,越發(fā)現(xiàn)自己的渺小裂问,越要勇往直前。

-- EOF --
本文轉(zhuǎn)載自IMJCW
原文鏈接:PHP SESSION 自定義會話管理器

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末牛柒,一起剝皮案震驚了整個濱河市堪簿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌皮壁,老刑警劉巖椭更,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蛾魄,居然都是意外死亡虑瀑,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門滴须,熙熙樓的掌柜王于貴愁眉苦臉地迎上來舌狗,“玉大人,你說我怎么就攤上這事扔水⊥词蹋” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵魔市,是天一觀的道長主届。 經(jīng)常有香客問我,道長待德,這世上最難降的妖魔是什么岂膳? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮磅网,結(jié)果婚禮上谈截,老公的妹妹穿的比我還像新娘。我一直安慰自己涧偷,他們只是感情好簸喂,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著燎潮,像睡著了一般喻鳄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上确封,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天除呵,我揣著相機與錄音再菊,去河邊找鬼。 笑死颜曾,一個胖子當(dāng)著我的面吹牛纠拔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播泛豪,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼稠诲,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了诡曙?” 一聲冷哼從身側(cè)響起臀叙,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎价卤,沒想到半個月后劝萤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡慎璧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年稳其,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片炸卑。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡既鞠,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出盖文,到底是詐尸還是另有隱情嘱蛋,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布五续,位于F島的核電站洒敏,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏疙驾。R本人自食惡果不足惜凶伙,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望它碎。 院中可真熱鬧函荣,春花似錦、人聲如沸扳肛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挖息。三九已至金拒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間套腹,已是汗流浹背绪抛。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工资铡, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人幢码。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓笤休,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蛤育。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容