自动化时间戳

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

准备

  1. 按照官方指南http://www.yiiframework.com/doc-2.0/guide-start-installation.html的描述,使用Composer包管理器创建一个新的应用。
  2. 设置数据库连接并创建一个表名叫blog_post
  1. DROP TABLE IF EXISTS 'blog_post';
  2. CREATE TABLE IF NOT EXISTS 'blog_post' (
  3. 'id' INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  4. 'title' VARCHAR(255) NOT NULL,
  5. 'text' TEXT NOT NULL,
  6. 'created_date' INTEGER,
  7. 'modified_date'INTEGER,
  8. PRIMARY KEY ('id')
  9. );
  1. 使用Gii为blog_post表创建一个模型。

如何做…

  1. 将如下方法添加到models/BlogPost.php
  1. /**
  2. * @return array
  3. */
  4. public function behaviors()
  5. {
  6. return [
  7. 'timestamp'=> [
  8. 'class' => 'yii\behaviors\TimestampBehavior',
  9. 'createdAtAttribute' => 'creation_date',
  10. 'updatedAtAttribute' => 'modified_date'
  11. ]
  12. ];
  13. }
  1. 创建controllers/TestController.php
  1. <?php
  2. namespace app\controllers;
  3. use app\models\BlogPost;
  4. use yii\helpers\Html;
  5. use yii\helpers\VarDumper;
  6. use yii\web\Controller;
  7. /**
  8. * Class TestController.
  9. * @package app\controllers
  10. */
  11. class TestController extends Controller
  12. {
  13. public function actionIndex()
  14. {
  15. $blogPost = new BlogPost();
  16. $blogPost->title = 'Gotcha!';
  17. $blogPost->text = 'We need some laughter to ease the
  18. tension of holiday shopping.';
  19. $blogPost->save();
  20. return $this->renderContent(Html::tag('pre',
  21. VarDumper::dumpAsString($blogPost->attributes)
  22. ));
  23. }
  24. }
  1. 现在运行test/index,你将会得到如下结果:

自动化时间戳 - 图1

工作原理…

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

更多…

例如我们的字段名称是creation_datemodified_date

根据这些字段使用behavior来配置我们的模型。此外,我们应该添加我们的behavior的代码到我们的Post模型:

  1. <?php
  2. namespace app\models;
  3. use Yii;
  4. use yii\db\BaseActiveRecord;
  5. class Post extends \yii\db\ActiveRecord
  6. {
  7. // ..
  8. public function behaviors()
  9. {
  10. return [
  11. [
  12. 'class' => 'yii\behaviors\TimestampBehavior',
  13. 'attributes' => [
  14. BaseActiveRecord::EVENT_BEFORE_INSERT =>
  15. 'creation_date',
  16. BaseActiveRecord::EVENT_BEFORE_UPDATE =>
  17. 'modified_date',
  18. ]
  19. ]
  20. ];
  21. }
  22. // ..
  23. }

在这个例子中,我们设定了creation_datemodified_date,在创建和更新时分别使用如下事件:EVENT_BEFORE_INSERTEVENT_BEFORE_UPDATE

其它…

在一些场景中,你可能希望保存时间戳。例如你希望给一个特定的控制器动作更新last_login字段。在这种情况下,你可以使用如下方式触发时间戳更新:

  1. $model->touch('last_login');

注意touch()不能用于新模型,否则你得到InvalidCallException异常:

  1. $model = new Post();
  2. $model->touch('creation_date');

touch()方法在它内部调用模型保存,所以你不需要再次调用。

参考

欲了解更多信息,参考http://www.yiiframework.com/doc-2.0/guide-conceptbehaviors.html#using-timestampbehavior