Yii2.0.31中时间戳自动填充依赖TimestampBehavior触发、字段为safe属性且类型匹配;需在rules()中声明safe或default,数据库设CURRENT_TIMESTAMP兜底,禁用手动赋值。

在 Yii2.0.31 中,时间戳字段(如 created_at、updated_at)为空时能自动填入默认值,关键不在“强行赋值”,而在于**行为触发 + 字段可写 + 类型匹配**三者协同。直接在控制器里手动写 $model->created_at = time() 不但冗余,还容易被覆盖或遗漏,也不利于 REST 场景统一管理。
确保 TimestampBehavior 正确绑定并生效
Yii 的 TimestampBehavior 是实现自动时间管理的核心,但它不是“开了就一定管用”。常见失效原因其实是字段没进模型的“安全属性列表”——比如 REST 接口调用 $model->load($post) 时,若 created_at 没被声明为 safe,它根本不会被加载,行为也就无从触发。
- 在模型的
rules()中显式加一条:['created_at', 'safe']或['created_at', 'default', 'value' => time()](后者仅用于 default 场景,不推荐替代 behavior) - 检查
scenarios()是否保留了 default 场景下的时间戳字段;如果重写了该方法,记得包含:self::SCENARIO_DEFAULT => ['created_at', 'updated_at', ...] - 行为应在
behaviors()中配置,且字段名必须与数据库列名完全一致(如用datetime类型,别写成created_at_int)
数据库层配合:用 CURRENT_TIMESTAMP 做兜底
即使 PHP 层因某种原因未触发行为(如跳过验证、绕过 save 流程),MySQL 的默认值机制可作为第二道防线。
- 建表时设置:
created_at DATETIME DEFAULT CURRENT_TIMESTAMP - 更新时间建议用:
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(注意类型用TIMESTAMP更稳妥,兼容性更好) - 迁移文件中可这样写:
$this->addColumn('user', 'created_at', $this->dateTime()->notNull()->defaultValue(new \yii\db\Expression('CURRENT_TIMESTAMP')));
避免手动赋值干扰自动逻辑
很多坑来自“多此一举”:比如在控制器里先 $model->load(),再手动设时间,最后 save() —— 这样 behavior 的 beforeInsert 就被绕过了,而且可能和数据库默认值冲突。
- 删除所有类似
$model->created_at = time()的硬编码 - 若需自定义时间(如创建时用某个特定时间点),改用 behavior 的
value回调:'value' => function() { return strtotime('2026-10-01'); } - REST 场景下尤其注意:不要在
actions()或beforeAction()里干预时间字段值
验证字段是否真正“可空”或“需默认”
有时字段为空却没触发默认逻辑,是因为规则里把它设成了 required,导致验证失败后直接中断流程,behavior 根本没机会运行。
- 时间戳字段一般不应出现在
required规则里,除非业务强要求前端传值 - 如果允许为空,又希望有默认值,就别加
required,而是靠 behavior 或 DB 默认值补全 - 可在
rules()中加注释提醒:// created_at: auto-filled by TimestampBehavior + DB DEFAULT


















