2009-10-30 81 views
3

根據我的理解,在Zend Framework中處理日期的最好方法是從數據庫中選擇它們作爲Unix時間戳。從Zend_Date對象中自動選擇數據庫中的日期

Quick Creation of Dates from Database Date Values

// SELECT UNIX_TIMESTAMP(my_datetime_column) FROM my_table 
$date = new Zend_Date($unixtimestamp, Zend_Date::TIMESTAMP); 

,我認爲這是一個痛苦,實際上是存在於甲骨文沒有簡單的方法要麼選擇日期爲Unix的時間戳或ISO-8601格式 - 這兩種格式Zend_Date最清楚。

但我確實寫了一個函數來選擇日期作爲PL/SQL中的unix時間戳,所以我現在可以實際做到這一點。

使用Zend_Db_Expr,現在我可以選擇我的時間存在的Unix時間戳:

$select = $db->select() 
      ->from(array('p' => 'products'), 
        array(
         'product_id', 
         'product_date' => new Zend_Db_Expr('toUnixTimestamp(product_date)') 
        ) 
       ); 

$results = $db->fetchAll($select); 

你會使用類似的查詢任何關係數據庫管理系統 - 最有時間戳功能。

我覺得這是煩人,因爲現在我通過$必須循環結果時間戳轉換爲手動Zend_Date對象:

foreach($results as $result){ 
    $productDate = new Zend_Date($result['product_date'], Zend_Date::TIMESTAMP); 
    echo $productDate->toString('dd/MMM/yyyy HH:mm:ss'); 
} 

我希望我的模型返回,其中時間戳已經轉化爲Zend_Date的運算$結果。我不想在每個數據訪問函數中寫一個循環來爲我做這件事。

所以要到我的實際問題的要點:

有誰知道與Zend_Db的一種方式,來建立某種形式的後處理上的結果集,從而把時間戳Zend_Date的運算自動對象?

回答

6

我遇到過我想要這樣做的場景。下面是我使用的解決方案:創建一個擴展行類一個Zend_Db_Table_Row

  • 和超載的__get()和__set()超方法
  • 在特定的類/我想用表Date對象,建立適當的方法來完成繁重的

這裏是我在我的項目中使用擴展列類的簡單化下來的版本:

/** 
* @category FireUp 
* @package FireUp_Db 
* @copyright Copyright (c) 2007-2009 Fire Up Media, Inc. (http://www.fireup.net) 
* @license http://dev.fireup.net/license/mit  MIT License 
* @uses  Zend_Db_Table_Row 
*/ 
class FireUp_Db_Table_Row extends Zend_Db_Table_Row_Abstract 
{ 
    /** 
    * Retrieve row field value 
    * 
    * Checks for the existence of a special method to apply additional handling for the field data and calls the method if it exists 
    * 
    * @param string $columnName The user-specified column name. 
    * @return string    The corresponding column value. 
    * @throws Zend_Db_Table_Row_Exception if the $columnName is not a column in the row. 
    */ 
    public function __get($key) 
    { 
     $inflector = new Zend_Filter_Word_UnderscoreToCamelCase(); 

     $method = '_get' . $inflector->filter($key); 

     if (method_exists($this, $method)) 
     { 
      return $this->{$method}(); 
     } 

     return parent::__get($key); 
    } 

    /** 
    * Set row field value 
    * 
    * Checks for the existence of a special method to apply additional handling for the field data and calls the method if it exists 
    * 
    * @param string $columnName The column key. 
    * @param mixed $value  The value for the property. 
    * @return void 
    * @throws Zend_Db_Table_Row_Exception 
    */ 
    public function __set($key, $value) 
    { 
     $inflector = new Zend_Filter_Word_UnderscoreToCamelCase(); 

     $method = '_set' . $inflector->filter($key); 

     if (method_exists($this, $method)) 
     { 
      return $this->{$method}($value); 
     } 

     return parent::__set($key, $value); 
    } 
} 

對於我們每一個人的表類,我們覆蓋的功能,例如:

class EntityRecord extends FireUp_Db_Table_Row 
{ 
    protected function _getDateCreated() 
    { 
     return new Zend_Date($this->_data['date_created'], Zend_Date::ISO_8601); 
    } 

    protected function _setDateCreated($value) 
    { 
     if ($value instanceof Zend_Date) 
     { 
      $value = $value->toString('YYYY-MM-dd HH:mm:ss'); 
     } 

     $this->_data['date_created'] = $value; 
     $this->_modifiedFields['date_created'] = true; 
    } 
} 

現在,創建一個新的Zend_Date對象每次該字段將訪問有一定的開銷,所以在我們班,我們採取額外措施,以高速緩存日期對象等等,但我不希望這會阻礙向您顯示解決方案。

+1

這是假設你使用Zend_Db_Table類並指定我會做同樣的方式模型 – gmcrist 2009-10-30 11:18:22

+0

行類。你可以在nZend_Db_Table之外的任何其他持久層中做同樣的事情;) – 2009-10-30 12:57:44

+0

代碼示例很好的回答! – 2009-10-30 21:01:28

0

使用Zend_Table並讓你的表返回你自定義的行對象extend Zend_Db_Table_Row_Abstract。然後只是在該行上有一個方法,如

function getDate() { 
    return new Zend_Date($this->datecol, Zend_Date::TIMESTAMP); 
} 
相關問題