2012-03-08 13 views
1

私は、ユーザーの作業時間をデータベースに記録するシステムを実装する必要があるZendのアプリケーションを持っています。 id_worktime、id_user、login_time、logout_timeがあります。ログインとログアウトは簡単ですが、ユーザーがgc_maxlifetimeよりも何もしないと問題があります。セッションテーブルに古い行が削除され、logout_timeがworktimeテーブルに更新されて - 私は、他のWebブラウザからリフレッシュを打つとき、それはうまく動作寿命が終わったときにZend Frameworkのどの部分がセッションオブジェクトをクリーニングしていますか?

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

    foreach ($garbage as $session) 
    { 
     $variables = array(); 
     $a = preg_split("/(\w+)\|/", $session['data'], -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) 
      { 
       $date = new Zend_Date($session['modified']); 
       $data['logout_time'] = $date->toString(Zend_Date::ISO_8601); 
       $worktimeTable = new Application_Model_DbTable_Worktime(); 
       $worktimeTable->update($data, 'id_worktime = '.$idWorktime); 
      } 
     } 
    } 

    parent::gc($maxlifetime); 
} 
} 

:私はここで、iは、GC()メソッドをオーバーライドZend_Session_SaveHandler_DbTableを拡張するクラスを書きました。しかし、ユーザーがログインしているWebブラウザでリフレッシュすると(現在セッションは期限切れです)、何も作業時間に入れられず、セッションの行が更新されます - 'modified'列は現在の時刻に設定され、 'data'

SessionPreferencesFlag|a:1:{s:16:"sessionSavedInDb";b:1;} 

(以前はZend_Authオブジェクトがありましたが、もっと多く、とりわけid_worktimeが必要です)。

これで、Zend Frameworkのどの部分がセッション行をクリアするのでしょうか?私はそれがZend_Sessionの何かだと思っていますが、実際それを見つけることはできません。いくつかの助けてください?

答えて

1

Zend_SessionはPHP組み込みのセッション機能の上に構築するので、ガベージコレクションの方法は、適切な場合、PHP自体によって呼び出されます。

あなたはZend_Session_SaveHandler_DbTableのソースコードを見てみるならば、私はあなたの問題は、それが正常にDBの外にセッションをロードしますが、それは期限が切れている見つけたらそこread()方法では、それは、削除、destroy()を呼び出すということだと思いますセッションデータ。これは、セッションが削除されたときの作業時間を更新する必要があるコードを 'バイパス'します。ガベージコレクション。あなたのコードの大部分をgc()から呼び出す別のメソッドに移動することをお勧めします。 destroy()メソッドを拡張して、新しいメソッドを呼び出すこともできます。

+0

ありがとうございます!あなたは正しい、私はどのように私はこれを逃すことができるか分からない:) – sas

1

私はこの問題を解決するために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); 
      } 
     } 
    } 
} 
関連する問題