当我们使用Yii数据库去保存Session时,只要简单的配置就可以完成这个功能,在进行性能优化这个主题之前,我们先来查看一下CHttpSession和CDBHttpSession源代码,探讨CHttpSession和CDBHttpSession的流程再进行深一步优化主题。
首先我们来先看下CHttpSession源码中的init,getUseCustomStorage,Open这三个方法
/**
* Initializes the application component.
* This method is required by IApplicationComponent and is invoked by application.
*/
public function init()
{
parent::init();
if($this->autoStart)
$this->open();
register_shutdown_function(array($this,'close'));
}
/**
* Returns a value indicating whether to use custom session storage.
* This method should be overriden to return true if custom session storage handler should be used.
* If returning true, make sure the methods {@link openSession}, {@link closeSession}, {@link readSession},
* {@link writeSession}, {@link destroySession}, and {@link gcSession} are overridden in child
* class, because they will be used as the callback handlers.
* The default implementation always return false.
* @return boolean whether to use custom storage.
*/
public function getUseCustomStorage()
{
return false;
}
/**
* Starts the session if it has not started yet.
*/
public function open()
{
if($this->getUseCustomStorage())
@session_set_save_handler(array($this,'openSession'),array($this,'closeSession'),array($this,'readSession'),array($this,'writeSession'),array($this,'destroySession'),array($this,'gcSession'));
if(@session_start()===false && YII_DEBUG)
{
$message=Yii::t('yii','Failed to start session.');
if(function_exists('error_get_last'))
{
$error=error_get_last();
if(isset($error['message']))
$message=$error['message'];
}
Yii::log($message, CLogger::LEVEL_WARNING, 'system.web.CHttpSession');
}
}
可以看到,当我们在protected/config/main.php文件组件配置中加入下面一行之后
'session' => array(
'timeout' => 300,
),
可以看到init方法里面将自动启动并调用open方法,getUseCustomStorage方法始终返回true,告诉Yii使用自定义方式管理Session,将session管理的方法全部注册到@session_set_save_handler 函数里面由PHP自动回调,所以我们如果需要扩展自定义的session管理方法,仅仅需要继承CHttpSession, 重写openSession,readSession,writeSession, destroySession,gcSession 这五个方法即可,可见Yii提供了非常简洁和强大扩展功能方式解决Session管理问题, 像CDbHttpSession 和 CCacheHttpSession扩展起来都非常方便。
接下来我们再看这五个方法的调用流程,分游客和登陆两种情况,我们来看CWebUser的源代之后就一目了然,看CWebUser::init方法,可以看到调用Yii::app()->getSession()->open(),由这里将开启一个新session.
/**
* Initializes the application component.
* This method overrides the parent implementation by starting session,
* performing cookie-based authentication if enabled, and updating the flash variables.
*/
public function init()
{
parent::init();
Yii::app()->getSession()->open();
if($this->getIsGuest() && $this->allowAutoLogin)
$this->restoreFromCookie();
else if($this->autoRenewCookie && $this->allowAutoLogin)
$this->renewCookie();
if($this->autoUpdateFlash)
$this->updateFlash();
$this->updateAuthStatus();
}
接下来将解释未登陆和登陆之前的流程:
当用户是游客时访问网站时首先将调用openSession, 打开session之后接着调用readSession, 然后调用writeSession.
当用户登陆之后,由CWebUser::login方法调用$this->changeIdentity($id,$identity->getName(),$states),再调用CHttpSession:: regenerateID重新生成sessionid方法,再调用readSession, writeSession.
public function login($identity,$duration=0)
{
$id=$identity->getId();
$states=$identity->getPersistentStates();
if($this->beforeLogin($id,$states,false))
{
$this->changeIdentity($id,$identity->getName(),$states); //由此方法调用
}
}
changeIdentity 方法
PHP代码
protected function changeIdentity($id,$name,$states)
{
Yii::app()->getSession()->regenerateID(); //由这里手动调用生成新的session id
$this->setId($id);
$this->setName($name);
$this->loadIdentityStates($states);
}
- 当用户退出时由CWebUser里面logout手动调用销毁当前session
public function logout($destroySession=true)
{
if($this->beforeLogout())
{
if($this->allowAutoLogin)
{
Yii::app()->getRequest()->getCookies()->remove($this->getStateKeyPrefix());
if($this->identityCookie!==null)
{
$cookie=$this->createIdentityCookie($this->getStateKeyPrefix());
$cookie->value=null;
$cookie->expire=0;
Yii::app()->getRequest()->getCookies()->add($cookie->name,$cookie);
}
}
if($destroySession)
Yii::app()->getSession()->destroy(); //由这里手动调用销毁
else
$this->clearStates();
$this->afterLogout();
}
}
- 当用户没有退出或者直接关闭浏览器时session并没有销毁,当session设定的timeout超过时,PHP将自动启动垃圾回收机制调用gcSession 将自动执行session清理动作。
'session' => array(
'timeout' => 300,
),
在这里,不用再多解释,相信大家已经清楚Yii 的Session执行过程,接下来我们将继续探讨Yii CDBHttpSession数据库存储session性能优化实战
原文出自: IT快讯网 连接: 关于Yii CHttpSession性能优化篇之源码流程分析
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.