在zend framework中,已经可以将session存储在数据库中了,不过还不支持memcache,我简单得实现了一下。
下面是SaveHandler,文件名为 :Memcached.php ,将其放在 /Zend/Session/SaveHandler 目录下,代码如下(需要有php_memcache支持,因为字符长度限制,我把部分注释去掉了):
require_once 'Zend/Session.php';
require_once 'Zend/Config.php';
class Zend_Session_SaveHandler_Memcached implements Zend_Session_SaveHandler_Interface
{
const LIFETIME = 'lifetime';
const OVERRIDE_LIFETIME = 'overrideLifetime';
const MEMCACHED = 'memcached';
protected $_lifetime = false;
protected $_overrideLifetime = false;
protected $_sessionSavePath;
protected $_sessionName;
protected $_memcached;
/**
* Constructor
*
* $config is an instance of Zend_Config or an array of key/value pairs containing configuration options for
* Zend_Session_SaveHandler_Memcached . These are the configuration options for
* Zend_Session_SaveHandler_Memcached:
*
*
* sessionId => The id of the current session
* sessionName => The name of the current session
* sessionSavePath => The save path of the current session
*
* modified => (string) Session last modification time column
*
* lifetime => (integer) Session lifetime (optional; default: ini_get('session.gc_maxlifetime'))
*
* overrideLifetime => (boolean) Whether or not the lifetime of an existing session should be overridden
* (optional; default: false)
*
* @param Zend_Config|array $config User-provided configuration
* @return void
* @throws Zend_Session_SaveHandler_Exception
*/
public function __construct($config)
{
if ($config instanceof Zend_Config) {
$config = $config->toArray();
} else if (!is_array($config)) {
/**
* @see Zend_Session_SaveHandler_Exception
*/
require_once 'Zend/Session/SaveHandler/Exception.php';
throw new Zend_Session_SaveHandler_Exception(
'$config must be an instance of Zend_Config or array of key/value pairs containing '
. 'configuration options for Zend_Session_SaveHandler_Memcached .');
}
foreach ($config as $key => $value) {
do {
switch ($key) {
case self::MEMCACHED:
$this->createMemcached($value);
break;
case self::LIFETIME:
$this->setLifetime($value);
break;
case self::OVERRIDE_LIFETIME:
$this->setOverrideLifetime($value);
break;
default:
// unrecognized options passed to parent::__construct()
break 2;
}
unset($config[$key]);
} while (false);
}
}
/**
* 创建memcached连接对象
*
* @return void
*/
public function createMemcached($config){
$mc = new Memcache;
foreach ($config as $value){
$mc->addServer($value['ip'], $value['port']);
}
$this->_memcached = $mc;
}
public function __destruct()
{
Zend_Session::writeClose();
}
/**
* Set session lifetime and optional whether or not the lifetime of an existing session should be overridden
*
* $lifetime === false resets lifetime to session.gc_maxlifetime
*
* @param int $lifetime
* @param boolean $overrideLifetime (optional)
* @return Zend_Session_SaveHandler_Memcached
*/
public function setLifetime($lifetime, $overrideLifetime = null)
{
if ($lifetime < 0) {
/**
* @see Zend_Session_SaveHandler_Exception
*/
require_once 'Zend/Session/SaveHandler/Exception.php';
throw new Zend_Session_SaveHandler_Exception();
} else if (empty($lifetime)) {
$this->_lifetime = (int) ini_get('session.gc_maxlifetime');
} else {
$this->_lifetime = (int) $lifetime;
}
if ($overrideLifetime != null) {
$this->setOverrideLifetime($overrideLifetime);
}
return $this;
}
/**
* Retrieve session lifetime
*
* @return int
*/
public function getLifetime()
{
return $this->_lifetime;
}
/**
* Set whether or not the lifetime of an existing session should be overridden
*
* @param boolean $overrideLifetime
* @return Zend_Session_SaveHandler_Memcached
*/
public function setOverrideLifetime($overrideLifetime)
{
$this->_overrideLifetime = (boolean) $overrideLifetime;
return $this;
}
public function getOverrideLifetime()
{
return $this->_overrideLifetime;
}
/**
* Retrieve session lifetime considering
*
* @param array $value
* @return int
*/
public function open($save_path, $name)
{
$this->_sessionSavePath = $save_path;
$this->_sessionName = $name;
return true;
}
/**
* Retrieve session expiration time
*
* @param * @param array $value
* @return int
*/
public function close()
{
return true;
}
public function read($id)
{
$return = '';
$value = $this->_memcached->get($id); //获取数据
if ($value) {
if ($this->_getExpirationTime($value) > time()) {
$return = $value['data'];
} else {
$this->destroy($id);
}
}
return $return;
}
public function write($id, $data)
{
$return = false;
$insertDate = array('modified' => time(),
'data' => (string) $data);
$value = $this->_memcached->get($id); //获取数据
if ($value) {
$insertDate['lifetime'] = $this->_getLifetime($value);
if ($this->_memcached->replace($id,$insertDate)) {
$return = true;
}
} else {
$insertDate['lifetime'] = $this->_lifetime;
if ($this->_memcached->add($id, $insertDate,false,$this->_lifetime)) {
$return = true;
}
}
return $return;
}
public function destroy($id)
{
$return = false;
if ($this->_memcached->delete($id)) {
$return = true;
}
return $return;
}
public function gc($maxlifetime)
{
return true;
}
protected function _getLifetime($value)
{
$return = $this->_lifetime;
if (!$this->_overrideLifetime) {
$return = (int) $value['lifetime'];
}
return $return;
}
protected function _getExpirationTime($value)
{
return (int) $value['modified'] + $this->_getLifetime($value);
}
}
配置(可以添加多台memcache服务器,做分布式):
$config = array(
'memcached'=> array(
array(
'ip'=>'192.168.0.1',
'port'=>11211
)
),
'lifetime' =>123334
);
//create your Zend_Session_SaveHandler_DbTable and
//set the save handler for Zend_Session
Zend_Session::setSaveHandler(new Zend_Session_SaveHandler_Memcached($config));
//start your session!
Zend_Session::start();
配置好后,session的使用方法和以前一样,不用管底层是怎么实现的!
阅读(2808) | 评论(0) | 转发(0) |