升级 yii2.0.28 后时间戳不自动更新,主因是 timestampbehavior 配置遗漏、数据库字段 default/on update 冲突以及时区不一致;需显式声明行为、统一交由 yii 或数据库控制、并校准时区与字段类型。

升级到 Yii2.0.28 后时间戳字段(如 created_at、updated_at)不再自动更新,通常不是框架“坏了”,而是行为配置、数据库字段定义或时区逻辑发生了隐性变化。核心问题集中在 TimestampBehavior 的触发条件与底层环境适配上,修复不需重写逻辑,关键在三处校准。
检查 TimestampBehavior 配置是否被覆盖或遗漏
Yii2.0.28 对行为初始化更严格,若模型中未显式声明 behaviors(),或父类 behavior 被子类空数组覆盖,时间戳将完全静默失效。确认每个需要时间戳的 ActiveRecord 类都包含完整配置:
- 不要依赖继承来的 behaviors() —— 即使父类已定义,子类也应显式 return 父类 + 自定义行为
- 避免写成
return [];或return array_merge(parent::behaviors(), [...]);却漏掉 timestamp 行为 - 确保
'class' => \yii\behaviors\TimestampBehavior::className()拼写准确(注意大小写和命名空间)
验证数据库字段类型与默认值冲突
MySQL 5.6+ 中,若 updated_at 字段设置了 DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,Yii 的 TimestampBehavior 默认不会覆盖该值(尤其当 value 未显式指定时),导致 PHP 层赋值被跳过。解决方式是“二选一”:
- 方案 A(推荐):移除数据库字段的 DEFAULT 和 ON UPDATE 定义,完全交由 Yii 行为控制,value 设为
new \yii\db\Expression('NOW()') - 方案 B:保留数据库自动更新,但 Yii 行为中设
'value' => null,并确保'attributes'映射正确,避免字段名拼错(如create_at少个 d) - 用
SHOW COLUMNS FROM user LIKE 'updated_at';检查实际字段定义,比代码更可信
排查时区与表达式兼容性问题
Yii2.0.28 加强了对数据库时区感知的校验。若应用时区(date_default_timezone_set())与 MySQL 服务器时区不一致,NOW() 可能生成错误时间;而使用 time() 函数又可能因服务器时间不准引入偏差。
- 统一用
new \yii\db\Expression('UTC_TIMESTAMP()')+ 应用层设 UTC 时区,避免本地时间漂移 - 若字段是 int 类型(UNIX 时间戳),
value必须是function () { return time(); },不能混用 Expression - PostgreSQL 用户请改用
'CURRENT_TIMESTAMP',且确保字段类型为TIMESTAMP WITHOUT TIME ZONE











