自动化时间戳
举个例子,我们有一个简单的博客应用。在任何一个博客中,有帖子、评论等等。我们希望在创建或者更新帖子时,生成时间戳。假设我们的帖子模型是BlogPost
。
准备
- 按照官方指南http://www.yiiframework.com/doc-2.0/guide-start-installation.html的描述,使用Composer包管理器创建一个新的应用。
- 设置数据库连接并创建一个表名叫
blog_post
:
DROP TABLE IF EXISTS 'blog_post';
CREATE TABLE IF NOT EXISTS 'blog_post' (
'id' INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
'title' VARCHAR(255) NOT NULL,
'text' TEXT NOT NULL,
'created_date' INTEGER,
'modified_date'INTEGER,
PRIMARY KEY ('id')
);
- 使用Gii为
blog_post
表创建一个模型。
如何做…
- 将如下方法添加到
models/BlogPost.php
:
/**
* @return array
*/
public function behaviors()
{
return [
'timestamp'=> [
'class' => 'yii\behaviors\TimestampBehavior',
'createdAtAttribute' => 'creation_date',
'updatedAtAttribute' => 'modified_date'
]
];
}
- 创建
controllers/TestController.php
:
<?php
namespace app\controllers;
use app\models\BlogPost;
use yii\helpers\Html;
use yii\helpers\VarDumper;
use yii\web\Controller;
/**
* Class TestController.
* @package app\controllers
*/
class TestController extends Controller
{
public function actionIndex()
{
$blogPost = new BlogPost();
$blogPost->title = 'Gotcha!';
$blogPost->text = 'We need some laughter to ease the
tension of holiday shopping.';
$blogPost->save();
return $this->renderContent(Html::tag('pre',
VarDumper::dumpAsString($blogPost->attributes)
));
}
}
- 现在运行
test/index
,你将会得到如下结果:
工作原理…
默认情况下,Timestamp behavior填充created_at
(创建模型时的时间戳)和updated_at
(更新模型时的时间戳)。这样命名这些字段是标准经验,但也可以根据实际需求进行修改。
更多…
例如我们的字段名称是creation_date
和modified_date
。
根据这些字段使用behavior来配置我们的模型。此外,我们应该添加我们的behavior的代码到我们的Post
模型:
<?php
namespace app\models;
use Yii;
use yii\db\BaseActiveRecord;
class Post extends \yii\db\ActiveRecord
{
// ..
public function behaviors()
{
return [
[
'class' => 'yii\behaviors\TimestampBehavior',
'attributes' => [
BaseActiveRecord::EVENT_BEFORE_INSERT =>
'creation_date',
BaseActiveRecord::EVENT_BEFORE_UPDATE =>
'modified_date',
]
]
];
}
// ..
}
在这个例子中,我们设定了creation_date
和modified_date
,在创建和更新时分别使用如下事件:EVENT_BEFORE_INSERT
和EVENT_BEFORE_UPDATE
。
其它…
在一些场景中,你可能希望保存时间戳。例如你希望给一个特定的控制器动作更新last_login
字段。在这种情况下,你可以使用如下方式触发时间戳更新:
$model->touch('last_login');
注意touch()
不能用于新模型,否则你得到InvalidCallException
异常:
$model = new Post();
$model->touch('creation_date');
touch()
方法在它内部调用模型保存,所以你不需要再次调用。
参考
欲了解更多信息,参考http://www.yiiframework.com/doc-2.0/guide-conceptbehaviors.html#using-timestampbehavior