当我们使用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); }
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' => array( 'timeout' => 300, ),
在这里,不用再多解释,相信大家已经清楚Yii 的Session执行过程,接下来我们将继续探讨Yii CDBHttpSession数据库存储session性能优化实战
原文出自: IT快讯网 连接: 关于Yii CHttpSession性能优化篇之源码流程分析
Be the first person to leave a comment
Please login to leave your comment.