Yii框架启用时间戳需同步配置TimestampBehavior、数据库DATETIME字段及PHP/MySQL/Yii三处时区为Asia/Shanghai,使用yii\db\Expression('NOW()')确保数据库生成时间。

Yii框架模型中开启时间戳,核心是配置 TimestampBehavior 并确保数据库字段、时区、模型定义三者对齐。不是加几行代码就完事,漏掉任一环节都可能造成时间写入为 0、时区偏移或更新不生效。
数据库字段必须存在且类型匹配
表中需有 created_at 和 updated_at 字段(字段名可自定义,但要与行为配置一致)。推荐使用 DATETIME 类型(非 TIMESTAMP),避免 MySQL 自动时区转换干扰:
created_at DATETIME NOT NULL DEFAULT '1970-01-01 00:00:00'updated_at DATETIME NOT NULL DEFAULT '1970-01-01 00:00:00'
若用 TIMESTAMP,MySQL 会按服务器时区自动转换,易与时区配置冲突;DATETIME 更可控,由 PHP 层统一管理。
模型中正确声明 behaviors()
在模型类中重写 behaviors() 方法,返回行为配置。关键点:用 yii\db\Expression('NOW()') 而非 time() 或闭包,确保数据库生成时间(精度高、时区由 MySQL 控制):
public function behaviors()
{
return [
[
'class' => \yii\behaviors\TimestampBehavior::class,
'createdAtAttribute' => 'created_at',
'updatedAtAttribute' => 'updated_at',
'attributes' => [
\yii\db\ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'],
\yii\db\ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'],
],
'value' => new \yii\db\Expression('NOW()'),
],
];
}
注意:value 不要写成 function () { return date('Y-m-d H:i:s'); } —— 这会在 PHP 层生成时间,受 PHP 时区影响,且无法利用 MySQL 的事务一致性。
PHP 和 MySQL 时区必须统一为 Asia/Shanghai
时间戳错 8 小时,90% 是时区没对齐。三处必须同时设为东八区:
- PHP 底层:修改
php.ini中date.timezone = "Asia/Shanghai",重启 PHP-FPM 和 Web 服务 - Yii 应用配置:在
config/web.php或common/config/main.php中添加'timeZone' => 'Asia/Shanghai' - MySQL 服务端:执行
SET GLOBAL time_zone = '+08:00';,并确认my.cnf中有default-time-zone='+08:00'
三者缺一不可。只配 Yii 的 timeZone,而 PHP 或 MySQL 仍是 UTC,NOW() 返回的仍是 UTC 时间。
验证是否生效的简单方法
新增一条记录后,直接查数据库:
- 检查
created_at是否为当前北京时间(非 1970 或 0000) - 执行一次
$model->save(),再查updated_at是否变化且晚于created_at - 用
var_dump($model->created_at, $model->updated_at)看模型属性值,应为字符串格式如"2026-08-17 14:38:22",而非时间戳整数
如果属性为空或为 0,先检查字段是否允许 NULL 或默认值是否干扰;如果时间正确但显示为 8 小时前,问题一定出在视图层格式化或时区未同步。


















