如何将Unix时间戳与Doctrine Timestampable行为一起使用?我找到了以下代码片段here,但我不想在任何地方手动添加它:
$this->actAs('Timestampable', array(
'created' => array('name' => 'created_at',
'type' => 'integer',
'format' => 'U',
'disabled' => false,
'options' => array()),
'updated' => array('name' => 'updated_at',
'type' => 'integer',
'format' => 'U',
'disabled' => false,
'options' => array())));
实际上,这是一个比我最初想的要容易得到答案的问题...
让我们从您现在拥有的开始:
Doctrine_Record
Test
。Test
模型中,您要使用Timestampable
行为,但要使用UNIX时间戳,而不要使用datetime
值此问题的解决方案是不使用Doctrine随附的默认Timestampable
行为,而是使用您将定义的另一行为。这意味着,在您的模型中,setTableDefinition
方法的底部将有类似以下内容:
$this->actAs('MyTimestampable');
(我想这也可以在setUp
方法中使用,顺便说一句-实际上,也许这是真实的地方)
我们现在要做的是定义MyTimestampable
行为,因此它可以完成我们想要的操作。由于Doctrine的Doctrine_Template_Timestampable
已经很好地完成了((当然,格式除外)),因此我们将继承自它;希望这将意味着更少的代码来编写;-)
所以,我们这样声明行为类:
class MyTimestampable extends Doctrine_Template_Timestampable
{
// Here it will come ^^
}
现在,让我们看看在Doctrine的代码源中Doctrine_Template_Timestampable
的实际作用:
created_at
和updated_at
字段]$this->addListener(new Doctrine_Template_Listener_Timestampable($this->_options));
让我们看一下这个源;我们注意到这部分:
if ($options['type'] == 'date') {
return date($options['format'], time());
} else if ($options['type'] == 'timestamp') {
return date($options['format'], time());
} else {
return time();
}
这意味着如果两个created_at
和updated_at
字段的类型既不是date
也不是timestamp
,Doctrine_Template_Listener_Timestampable
将自动使用UNIX时间戳记-多么方便!
由于您不想在每个模型中都定义要用于这些字段的type
,因此我们将修改MyTimestampable
类。记住,我们说它正在扩展Doctrine_Template_Timestampable
,它负责行为的配置...
因此,我们使用type
和date
以外的timestamp
覆盖该配置:
class MyTimestampable extends Doctrine_Template_Timestampable
{
protected $_options = array(
'created' => array('name' => 'created_at',
'alias' => null,
'type' => 'integer',
'disabled' => false,
'expression' => false,
'options' => array('notnull' => true)),
'updated' => array('name' => 'updated_at',
'alias' => null,
'type' => 'integer',
'disabled' => false,
'expression' => false,
'onInsert' => true,
'options' => array('notnull' => true)));
}
我们之前说过,我们的模型是MyTimestampable
,而不是Timestampable
...所以,现在让我们来看结果;-)
如果我们考虑将此模型类用于Test
:
class Test extends Doctrine_Record
{
public function setTableDefinition()
{
$this->setTableName('test');
$this->hasColumn('id', 'integer', 4, array(
'type' => 'integer',
'length' => 4,
'unsigned' => 0,
'primary' => true,
'autoincrement' => true,
));
$this->hasColumn('name', 'string', 32, array(
'type' => 'string',
'length' => 32,
'fixed' => false,
'primary' => false,
'notnull' => true,
'autoincrement' => false,
));
$this->hasColumn('value', 'string', 128, array(
'type' => 'string',
'length' => 128,
'fixed' => false,
'primary' => false,
'notnull' => true,
'autoincrement' => false,
));
$this->hasColumn('created_at', 'integer', 4, array(
'type' => 'integer',
'length' => 4,
'unsigned' => 0,
'primary' => false,
'notnull' => true,
'autoincrement' => false,
));
$this->hasColumn('updated_at', 'integer', 4, array(
'type' => 'integer',
'length' => 4,
'unsigned' => 0,
'primary' => false,
'notnull' => false,
'autoincrement' => false,
));
$this->actAs('MyTimestampable');
}
}
哪个映射到以下MySQL表:
CREATE TABLE `test1`.`test` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(32) NOT NULL,
`value` varchar(128) NOT NULL,
`created_at` int(11) NOT NULL,
`updated_at` int(11) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
我们可以通过这种方式在表中创建两行:
$test = new Test();
$test->name = 'Test 1';
$test->value = 'My Value 2';
$test->save();
$test = new Test();
$test->name = 'Test 2';
$test->value = 'My Value 2';
$test->save();
如果我们检查数据库中的值,将会得到类似这样的内容:
mysql> select * from test;
+----+--------+----------------+------------+------------+
| id | name | value | created_at | updated_at |
+----+--------+----------------+------------+------------+
| 1 | Test 1 | My Value 1 | 1248805507 | 1248805507 |
| 2 | Test 2 | My Value 2 | 1248805583 | 1248805583 |
+----+--------+----------------+------------+------------+
2 rows in set (0.00 sec)
所以,对于行的创建,我们还可以;-)
现在,让我们获取并更新第二行:
$test = Doctrine::getTable('Test')->find(2);
$test->value = 'My New Value 2';
$test->save();
然后回到数据库,我们现在得到这个:
mysql> select * from test;
+----+--------+----------------+------------+------------+
| id | name | value | created_at | updated_at |
+----+--------+----------------+------------+------------+
| 1 | Test 1 | My Value 1 | 1248805507 | 1248805507 |
| 2 | Test 2 | My New Value 2 | 1248805583 | 1248805821 |
+----+--------+----------------+------------+------------+
2 rows in set (0.00 sec)
updated_at
字段已更新,并且created_at
字段未更改;似乎也行[[;-)
MyTimestampable
,而不是默认的Timestampable
class Base extends Doctrine_Record_Listener
{
public function preHydrate(Doctrine_Event $event)
{
$data = $event->data;
$data['unix_created_at'] = strtotime($data['created_at']);
$data['unix_updated_at'] = strtotime($data['updated_at']);
$event->data = $data;
}
}
这可能是您在所有需要created_at和Updated_at功能的情况下扩展的基类。
我敢肯定,您可以修改$ data并转换所有日期时间字段'unix _'。$ field_name。祝你好运