<blockquote>session字如其意,它的存在就是爲了保持會話狀態。PHP中的$_SESSION讓咱們很方便的使用它,可是若是PHP自己不提供這個功能,咱們該如何實現呢?且聽我慢慢忽悠。</blockquote> <h3>session的實現原理</h3> <p>session自己的實現原理其實很簡單,幾句話就能夠說完</p> <ul> <li>用戶首次訪問時生成惟一ID(其實就是PHP中的<code>session_id</code>)</li> <li>根據session_id做爲惟一標示,生成session_id爲名稱的文件(儲存session內容,固然也能夠存到redis或者mysql中)</li> <li>經過cookie下發<code>session_id</code>到客戶端</li> <li>用戶再次訪問時會經過cookie將<code>session_id</code>帶上</li> <li>服務端經過<code>session_id</code>獲取對應的session內容(文件、Cache、數據庫)</li> </ul> <h3>代碼實現</h3> <p>下面是我經過PHP實現的一個簡單的session功能類,用來演示具體的實現過程,只實現了寫和讀功能(沒有考慮會話有效期、併發等問題)。</p>mysql
/** * Session類簡單實現 * @author zhjx922 */ class Session { //當前sessionId private $_sessionId; //session的儲存路徑 private $_sessionPath = '/tmp/session'; /** * 初始化sessionId */ public function __construct() { if(isset($_COOKIE['PHPSESSID']) && $this->checkSession($_COOKIE['PHPSESSID'])) { $this->_sessionId = $_COOKIE['PHPSESSID']; } else { $this->_sessionId = uniqid(); setcookie("PHPSESSID", $this->_sessionId); } } /** * 設置session * @param string $key * @param mixed $value */ public function setSession($key, $value) { $sessionInfo = $this->getSessionInfo(); $sessionInfo[$key] = $value; $sessionFile = "{$this->_sessionPath}/{$this->_sessionId}"; file_put_contents($sessionFile, serialize($sessionInfo)); } /** * 獲取session * @param string $key * @return mixed */ public function getSession($key) { return $this->getSessionInfo()[$key]; } /** * 獲取當前sessionId下的內容 * @return array */ private function getSessionInfo() { if(!is_dir($this->_sessionPath)) { mkdir($this->_sessionPath); } $sessionFile = "{$this->_sessionPath}/{$this->_sessionId}"; if(is_file($sessionFile)) { $contents = file_get_contents($sessionFile); return unserialize($contents); } return []; } /** * 檢查session是否有效 * @param string $sessionId * @return bool */ private function checkSession($sessionId) { $sessionFile = "{$this->_sessionPath}/{$sessionId}"; if(is_file($sessionFile)) { return true; } return false; } }
<p>使用方法以下</p>redis
$session = new Session(); $session->setSession('a', 'b'); //第二次訪問時註釋掉這行,驗證下一行$session->getSession('a')輸出的內容是否正確 var_dump($session->getSession('a'));
<p>是否是特別簡單呢?使用每一個功能的時候多想一下它是怎麼實現的,不少時候可以讓咱們快速定位到問題的所在~</p>sql