yii模型时间戳需显式配置timestampbehavior,严格匹配字段名并用now()确保时区统一;php、yii、formatter三层timezone须同步为asia/shanghai,否则易错8小时。

Yii框架模型时间戳字段不能靠“自动识别”或“约定俗成”,必须显式配置行为(Behavior)或手动干预,否则 created_at、updated_at 这类字段不会自动写入或更新。
用 TimestampBehavior 统一管理(推荐)
这是最规范、可复用的方式,适用于 Yii 2.0+。需确保数据库表已存在对应字段(如 created_at DATETIME、updated_at DATETIME),并在模型中声明行为:
- 在模型的
behaviors()方法中返回TimestampBehavior配置 -
createdAtAttribute和updatedAtAttribute必须与数据库字段名严格一致(区分大小写) -
value推荐使用new \yii\db\Expression('NOW()'),让 MySQL 直接生成时间,避免 PHP 时区偏差 - 若字段类型是
TIMESTAMP,MySQL 可能自动设默认值;但为跨库兼容,仍建议由 PHP 层控制
确保时区统一,否则时间错 8 小时
时间戳不准,90% 是时区没对齐。必须三层同步:
- PHP 底层:修改
php.ini中date.timezone = "Asia/Shanghai",并重启 Web 服务和 PHP-FPM - Yii 应用层:在
config/web.php或入口文件中设置'timeZone' => 'Asia/Shanghai' - Formatter 组件:同时配置
'formatter' => ['class' => 'yii\i18n\Formatter', 'timeZone' => 'Asia/Shanghai']
避免踩坑的细节
很多问题其实出在小细节上:
- 不写
tableName()方法会导致 AR 找不到表,时间戳行为根本不会触发 - 主键不是
id?记得重写primaryKey(),否则save()可能失败,时间字段也写不进去 - 用
rules()设置默认值(如['created_at', 'default', 'value' => new Expression('NOW()')])虽可行,但不如 Behavior 灵活,且无法区分 insert/update 场景 - 前端表单提交日期时,
CJuiDatePicker的dateFormat必须匹配后端接收格式(如"yyyy-mm-dd"),否则created_at可能被当成字符串存成0000-00-00 00:00:00
验证是否生效的小技巧
调试时快速确认时间戳是否正常工作:
- 新建一条记录,检查数据库中
created_at和updated_at是否一致且为当前时间 - 更新同一条记录,再查库——
created_at不变,updated_at应刷新 - 临时在模型
beforeSave()里加var_dump($this->isNewRecord, $this->created_at, $this->updated_at); die;,看值是否按预期生成











