Php 生命周期结束时,Zend框架的哪个部分正在清理会话对象?

Php 生命周期结束时,Zend框架的哪个部分正在清理会话对象?,php,zend-framework,session,Php,Zend Framework,Session,我在Zend中有一个应用程序,我需要实现一个系统,该系统将用户的工作时间记录到数据库中。有id\u工作时间、id\u用户、登录时间和注销时间。登录和注销很容易,但当用户不做任何超过gc_maxlifetime的事情时就会出现问题。我编写了扩展Zend_Session_SaveHandler_DbTable的类,其中重写了gc()方法: (之前有Zend_Auth对象和更多,以及我需要的id_工作时间) 现在的问题是——Zend框架的哪个部分清除了该会话行?我想这是在Zend_会议上,但我真的找不

我在Zend中有一个应用程序,我需要实现一个系统,该系统将用户的工作时间记录到数据库中。有id\u工作时间、id\u用户、登录时间和注销时间。登录和注销很容易,但当用户不做任何超过gc_maxlifetime的事情时就会出现问题。我编写了扩展Zend_Session_SaveHandler_DbTable的类,其中重写了gc()方法:

(之前有Zend_Auth对象和更多,以及我需要的id_工作时间)


现在的问题是——Zend框架的哪个部分清除了该会话行?我想这是在Zend_会议上,但我真的找不到它。请提供一些帮助?

Zend_会话
基于内置的PHP会话功能,因此在适当的情况下,PHP本身会调用垃圾收集方法


如果查看
Zend\u Session\u SaveHandler\u DbTable
的源代码,我认为您的问题在于,在那里的
read()
方法中,如果它成功地从数据库中加载了一个会话,但发现它已过期,它将调用
destroy()
,删除会话数据。这“绕过”了通过删除会话时必须更新工作时间的代码。垃圾收集。我建议将大部分代码转移到另一个方法,您可以从
gc()
调用该方法。然后,您还可以扩展
destroy()
方法,让它也调用新方法。

多亏了Tim Fountain,我成功地解决了这个问题。工作代码:

class Vao_Session extends Zend_Session_SaveHandler_DbTable
{   
    public function read($id)
    {
        $return = '';

        $rows = call_user_func_array(array(&$this, 'find'), $this->_getPrimary($id));

        if (count($rows)) {
            if ($this->_getExpirationTime($row = $rows->current()) > time()) {
                $return = $row->{$this->_dataColumn};
            } else {
                $this->_saveLogoutTime($row);
                $this->destroy($id);
            }
        }

        return $return;
    }

    public function gc($maxlifetime)
    {
        $garbage = $this->fetchAll($this->select()->from('session')->where('`modified` + `lifetime` < ?', time()));

        foreach ($garbage as $session)
        {
            $this->_saveLogoutTime($session);
        }

        parent::gc($maxlifetime);
    }

    private function _saveLogoutTime($sessionRow)
    {
        $variables = array();
        $a = preg_split("/(\w+)\|/", $sessionRow[$this->_dataColumn], -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
        for($i = 0; $i < count($a); $i = $i + 2){
            $variables[$a[$i]] = unserialize($a[$i + 1]);
        }

        if (isset($variables['worktime']))
        {
            $worktime = $variables['worktime'];
            $idWorktime = $worktime['id_worktime'];

            if ($idWorktime)
            {
                $data = array();
                $date = new Zend_Date($sessionRow[$this->_modifiedColumn]);
                $data['logout_time'] = $date->toString(Zend_Date::ISO_8601);
                $worktimeTable = new Application_Model_DbTable_Worktime();
                $worktimeTable->update($data, 'id_worktime = '.$idWorktime);
            }
        }
    }
}
class Vao_Session扩展了Zend_Session_SaveHandler_DbTable
{   
公共函数读取($id)
{
$return='';
$rows=call_user_func_数组(数组(&$this,'find'),$this->\u getPrimary($id));
如果(计数($行)){
如果($this->_getExpirationTime($row=$rows->current())>time()){
$return=$row->{$this->_dataColumn};
}否则{
$this->_saveLogoutTime($row);
$this->destroy($id);
}
}
return$return;
}
公共函数gc($maxlifetime)
{
$garbage=$this->fetchAll($this->select()->from('session')->where('modified`+'lifety`<?',time());
foreach($garbage as$session)
{
$this->u saveLogoutTime($session);
}
父::gc($maxlifest);
}
私有函数_saveLogoutTime($sessionRow)
{
$variables=array();
$a=preg_split(“/(\w+)\|/”,$sessionRow[$this->_dataColumn],-1,preg_split_NO_EMPTY | preg_split_DELIM_CAPTURE);
对于($i=0;$i_modifiedColumn]);
$data['logout\u time']=$date->toString(Zend\u date::ISO\u 8601);
$worktimeline=新应用程序\模型\数据库\工作时间();
$worktimeline->update($data,'id\u worktime='。$idWorktime);
}
}
}
}

谢谢!你说得对,我不知道我怎么会错过这个:)
SessionPreferencesFlag|a:1:{s:16:"sessionSavedInDb";b:1;}
class Vao_Session extends Zend_Session_SaveHandler_DbTable
{   
    public function read($id)
    {
        $return = '';

        $rows = call_user_func_array(array(&$this, 'find'), $this->_getPrimary($id));

        if (count($rows)) {
            if ($this->_getExpirationTime($row = $rows->current()) > time()) {
                $return = $row->{$this->_dataColumn};
            } else {
                $this->_saveLogoutTime($row);
                $this->destroy($id);
            }
        }

        return $return;
    }

    public function gc($maxlifetime)
    {
        $garbage = $this->fetchAll($this->select()->from('session')->where('`modified` + `lifetime` < ?', time()));

        foreach ($garbage as $session)
        {
            $this->_saveLogoutTime($session);
        }

        parent::gc($maxlifetime);
    }

    private function _saveLogoutTime($sessionRow)
    {
        $variables = array();
        $a = preg_split("/(\w+)\|/", $sessionRow[$this->_dataColumn], -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
        for($i = 0; $i < count($a); $i = $i + 2){
            $variables[$a[$i]] = unserialize($a[$i + 1]);
        }

        if (isset($variables['worktime']))
        {
            $worktime = $variables['worktime'];
            $idWorktime = $worktime['id_worktime'];

            if ($idWorktime)
            {
                $data = array();
                $date = new Zend_Date($sessionRow[$this->_modifiedColumn]);
                $data['logout_time'] = $date->toString(Zend_Date::ISO_8601);
                $worktimeTable = new Application_Model_DbTable_Worktime();
                $worktimeTable->update($data, 'id_worktime = '.$idWorktime);
            }
        }
    }
}