将时间戳字段水合到PEAR Date对象

时间:2011-03-11 20:39:16

标签: php doctrine doctrine-1.2

在我的Symfony / Doctrine应用程序中,我希望我的数据库中的任何时间戳字段都可以作为PEAR Date对象而不是日期字符串进行检索。例如如果我的架构是

SomeEvent:
   columns:
      id:
         type: integer
         primary: true
      start: timestamp
      end: timestamp

我希望能够运行Doctrine查询来检索SomeEvent个对象,并让$anEvent->getStart()成为PEAR Date对象。现在Doctrine给了我所有时间戳字段的字符串,基本上没用。 (我也希望保存日期才能正常工作。)

实现这一目标的最佳方法是什么?

我研究过使用Hydration监听器,但看起来我必须在每个表中注册并硬编码我想要转换的列名。使用定制的Hydrator看起来并没有那么好,因为我失去了使用任何其他核心水合方法的能力,而不会让我的日期再次成为字符串。

编辑:看起来Doctrine 2的功能正是我所期待的:Custom Mapping Types。不幸的是,这个站点被部署到不支持PHP 5.3+的主机上,因此Doctrine 2已经发布了。 :(

1 个答案:

答案 0 :(得分:0)

我想出了一个黑客的做法,我不是很满意,但它确实有效。我创建了以下两个类:

class DateClassBehavior extends Doctrine_Template {

   public function setTableDefinition() {
      $listener = new DateClassListener();
      $table = $this->getTable();

      foreach ($table->getColumns() as $columnName => $columnDef) {
         if ($columnDef['type'] == 'timestamp') {
            $listener->dateColumns[] = $columnName;
         }
      }

      $this->addListener($listener);
   }

}

class DateClassListener extends Doctrine_Record_Listener {

   public $dateColumns = array();

   public function postHydrate(Doctrine_Event $event) {
      $data = $event->data;

      foreach ($this->dateColumns as $col) {
         $date = $data->$col == null ? null : new Date($data->$col);
         $data->$col = null;
         $data->$col = $date;
      }

      $event->data = $data;
   }

}

并将DateClassBehavior添加到我模型中每个表的定义中:

SomeEvent:
   actAs: [DateClassBehavior]
   columns:
      id:
         type: integer
         primary: true
      start: timestamp
      end: timestamp

这会在加载内容时创建Date对象。我还修改了实际的PEAR Date类(我知道......不好)并添加了一个返回__toString()的{​​{1}}方法。然后,当doctrine保存日期时,PHP会自动将日期转换为正确的字符串。

如果有人找到更好的方法,请发布。