CookieStoreなセッションの試み
Rails 2からデフォルトになってるCookieStoreなセッションいいなーと思ったのでkarinto_session2とか試しに作ってみた。どうするか未定。
レンタルサーバーでPHPを使うときって、ストレージを考えるとセッションが使いづらい。DBに保存してもいいけど管理面倒だし。そう考えると、クライアント側のCookieに保存するのは便利。Cookieを扱えない携帯電話とかは無視する方向で(そんなもんブラウザが悪い)。
<?php class karinto_session2 { const default_secret_key = 'karinto_session_secret_key'; const cookie_name = '_karinto_app_session'; protected $_vars; public function __construct() { if (karinto::$session_secret_key === self::default_secret_key) { throw new karinto_session('secret key not changed'); } $this->_vars = $this->_restore(); } public function __destruct() { $this->_write(); } public function __set($name, $value) { $this->_vars[$name] = $value; } public function __get($name) { if (isset($this->_vars[$name])) { return $this->_vars[$name]; } return null; } public function __isset($name) { return isset($this->_vars[$name]); } public function __unset($name) { if (isset($this->_vars[$name])) { unset($this->_vars[$name]); } } protected function _restore() { if (!isset($_COOKIE[self::cookie_name])) { return array(); } $cookie_data = $_COOKIE[self::cookie_name]; if (get_magic_quotes_gpc()) { $cookie_data = stripslashes($cookie_data); } list($data, $digest_data) = explode('--', $cookie_data); if (is_null($data) || is_null($digest_data)) { $this->_destroy(); return array(); } $data = @unserialize(base64_decode($data)); if ($data === false || !is_array($data)) { $this->_destroy(); return array(); } if ($this->_generate_digest($data) !== $digest_data) { $this->_destroy(); return array(); } return $data; } protected function _write() { // TODO check: length < 4KB $data = base64_encode(serialize($this->_vars)); $digest_data = $this->_generate_digest($this->_vars); $cookie_data = $data . '--' . $digest_data; $this->_set_cookie($cookie_data); } protected function _destroy() { $this->_set_cookie('', -3600); } protected function _generate_digest($data) { $data = serialize($data); return sha1(karinto::$session_secret_key . $data); } protected function _set_cookie($value, $lifetime = null) { // use session settings $param = session_get_cookie_params(); if (is_null($lifetime)) { $lifetime = $param['lifetime']; } $expire = time() + $lifetime; if (empty($param['domain']) && empty($param['secure'])) { setcookie(self::cookie_name, $value, $expire, $param['path']); } else if (empty($param['secure'])) { setcookie(self::cookie_name, $value, $expire, $param['path'], $param['domain']); } else { setcookie(self::cookie_name, $value, $expire, $param['path'], $param['domain'], $param['secure']); } } }
あー、セッションタイムアウトのこととか考えてないや。考慮しないと。