在 yii 中为数据库表添加时间戳字段需同时配置迁移文件和模型行为:迁移中用整型或 datetime 类型定义字段,模型中启用 timestampbehavior 并设置 createdatattribute、updatedatattribute 及 value 表达式,还需统一 php 与 mysql 时区。

在 Yii 框架中,迁移文件里为数据库表添加时间戳字段(如 created_at、updated_at)需兼顾数据库层面默认值与应用层自动填充逻辑。直接用 datetime DEFAULT CURRENT_TIMESTAMP 不足以满足 Yii 的行为预期,尤其在更新时需自动刷新 updated_at,还需配合模型或行为(如 TimestampBehavior)协同工作。
数据库迁移中定义时间戳字段(MySQL 示例)
在迁移类的 up() 方法中,推荐使用 Yii 提供的抽象类型(如 datetime() 或 integer()),并根据是否需要自动更新来选择策略:
- 若用 DATETIME 类型且依赖数据库自动维护(MySQL 5.6+),可写:
$this->addColumn('user', 'created_at', $this->dateTime()->notNull()->defaultValue(new \yii\db\Expression('CURRENT_TIMESTAMP')));$this->addColumn('user', 'updated_at', $this->dateTime()->notNull()->defaultValue(new \yii\db\Expression('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'))); - 更通用、跨数据库兼容的做法是存为整型时间戳(Unix timestamp),便于 Yii 行为统一处理:
$this->addColumn('user', 'created_at', $this->integer()->notNull()->defaultValue(0));$this->addColumn('user', 'updated_at', $this->integer()->notNull()->defaultValue(0));
模型中启用 TimestampBehavior(关键步骤)
仅建好字段不够,必须在对应 ActiveRecord 模型中配置行为,否则时间不会自动写入:
- 在模型类的
behaviors()方法中返回:return ['timestamp' => ['class' => \yii\behaviors\TimestampBehavior::class,'createdAtAttribute' => 'created_at','updatedAtAttribute' => 'updated_at','value' => new \yii\db\Expression('UNIX_TIMESTAMP()'), // MySQL],]; - 若字段是
datetime类型,把'value'改为:'value' => new \yii\db\Expression('NOW()')
注意时区与精度一致性
避免前后端时间错乱,需统一时区设置:
- PHP 层:确保
date_default_timezone_set('Asia/Shanghai');或在php.ini中配置 - MySQL 层:检查
SELECT @@global.time_zone, @@session.time_zone;,建议设为+08:00或SYSTEM并与 PHP 一致 - 若用整型时间戳,Yii 默认调用
time(),天然无时区转换;若用 DATETIME,NOW()返回的是 MySQL 服务器本地时间,务必对齐
验证与调试小技巧
执行迁移后,快速确认是否生效:
- 插入新记录后查数据库,看
created_at是否有值 - 调用
$model->save()更新数据,再查updated_at是否变化 - 临时在行为配置中加日志:
'value' => function () { \Yii::debug('Timestamp generated'); return time(); }
不复杂但容易忽略细节,尤其是整型 vs datetime 类型的选择、行为配置位置、以及时区对齐。按上述步骤操作,时间戳就能稳稳跑起来。











