Автоматический выбор дат из баз данных как объектов Zend_Date - PullRequest
3 голосов
/ 30 октября 2009

Насколько я понимаю, лучший способ работы с датами в Zend Framework - это выбрать их в качестве метки времени Unix из базы данных.

Быстрое создание дат из значений даты базы данных

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

Мне кажется, это боль в том, что в Oracle нет простого способа выбрать даты как метки времени Unix или в формате ISO-8601 - это два формата, которые Zend_Date знает лучше.

Но я написал функцию для выбора дат в качестве меток времени Unix в PL / SQL, так что теперь я могу это сделать.

Используя 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);

Вы бы использовали аналогичный запрос для любой RDMS - большинство имеют функцию отметки времени.

Я нахожу это раздражающим, потому что теперь я должен циклически просматривать $ results, чтобы вручную преобразовать метку времени в объект 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?

Ответы [ 2 ]

6 голосов
/ 30 октября 2009

Я сталкивался со сценариями, в которых я хотел это сделать. Вот решение, которое я использовал:

  • Создан расширенный класс строк для Zend_Db_Table_Row и перегружены супер-методы __get () и __set ()
  • В определенных классах / таблицах, в которых я хочу использовать объекты даты, созданы соответствующие методы для выполнения тяжелой работы

Вот упрощенная версия расширенного класса строк, который я использую в своих проектах:

/**
 * @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 каждый раз, когда к полю будет осуществляться доступ, имеет некоторые накладные расходы, поэтому в наших классах мы принимаем дополнительные меры для кэширования объектов даты и т. Д., Но я не хотел, чтобы это мешало показать вам решение.

0 голосов
/ 30 октября 2009

Используйте Zend_Table, и ваша таблица вернет вам пользовательские объекты строк, которые расширяются Zend_Db_Table_Row_Abstract. Затем просто укажите метод в этой строке, например

function getDate() {
    return new Zend_Date($this->datecol, Zend_Date::TIMESTAMP);
}
...