View on GitHub

yii2-cookbook-chinese

Yii Application Development Cookbook(Third Edition)中文翻译

自动化时间戳

举个例子,我们有一个简单的博客应用。在任何一个博客中,有帖子、评论等等。我们希望在创建或者更新帖子时,生成时间戳。假设我们的帖子模型是BlogPost

准备

  1. 按照官方指南http://www.yiiframework.com/doc-2.0/guide-start-installation.html的描述,使用Composer包管理器创建一个新的应用。
  2. 设置数据库连接并创建一个表名叫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')
);
  1. 使用Gii为blog_post表创建一个模型。

如何做…

  1. 将如下方法添加到models/BlogPost.php
/**
 * @return array
 */
public function behaviors()
{
    return [
        'timestamp'=> [
            'class' => 'yii\behaviors\TimestampBehavior',
            'createdAtAttribute' => 'creation_date',
            'updatedAtAttribute' => 'modified_date'
        ]
    ];
}
  1. 创建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)
        ));
    }
}
  1. 现在运行test/index,你将会得到如下结果:

工作原理…

默认情况下,Timestamp behavior填充created_at(创建模型时的时间戳)和updated_at(更新模型时的时间戳)。这样命名这些字段是标准经验,但也可以根据实际需求进行修改。

更多…

例如我们的字段名称是creation_datemodified_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_datemodified_date,在创建和更新时分别使用如下事件:EVENT_BEFORE_INSERTEVENT_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