yii 2.0.33 默认不启用全局自动时间戳,需逐模型检查并移除 timestampbehavior 配置、确保 rules() 中时间戳字段非 safe、排查基类或 trait 是否统一注入,同时注意数据库层面的自动更新设置以避免数据不一致。

Yii 2.0.33 中默认不开启全局自动时间戳,所谓“关闭”实际是指:避免 TimestampBehavior 被意外启用或干扰业务逻辑。它本身不是全局开关,而是按模型逐个配置的行为。因此,真正要做的不是“关掉一个全局设置”,而是确保时间戳字段不被自动管理——尤其在 RESTful 场景下容易因配置疏漏导致 created_at/updated_at 被覆盖或置 null。
检查模型中是否声明了 TimestampBehavior
TimestampBehavior 是手动绑定的,不会自动生效。若你的模型类里有类似以下代码,就说明启用了自动时间戳:
public function behaviors()
{
return [
'timestamp' => [
'class' => TimestampBehavior::className(),
'createdAtAttribute' => 'created_at',
'updatedAtAttribute' => 'updated_at',
],
];
}
要“关闭”它,直接删掉或注释掉这个 behavior 配置即可。
确认 rules() 中未将时间戳字段设为 safe
即使行为已移除,如果时间戳字段仍在 rules() 里被标记为 safe,REST 控制器仍可能通过 load() 接收并写入这些字段(比如前端传了 updated_at=0),造成意外覆盖。
应确保类似字段不参与批量赋值:
- 删掉 rules() 中类似
['created_at', 'updated_at', 'safe']的规则 - 如需保留校验但禁止赋值,可改用
['created_at', 'required', 'on' => 'insert']等显式场景控制 - 或在 scenarios() 中明确排除:例如
$this->detachBehavior('timestamp');在 beforeSave 里也可临时禁用
排查控制器或基类是否统一注入行为
有些项目会在基类 Model 或 ActiveRecord 子类中统一注册 TimestampBehavior,导致所有子模型都继承该行为。此时需定位到父类,检查其 behaviors() 方法是否硬编码了时间戳逻辑。
常见误操作包括:
- 在 base/ActiveRecord.php 中统一加 behavior,但子模型未重写 behaviors() 去覆盖
- 使用 traits 封装了行为,却在多个模型中 use 了该 trait
- REST 控制器里手动调用
$model->load($data)后又写了$model->updated_at = time();,这会绕过行为但留下隐患
数据库层面保持中立
MySQL 的 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP 是数据库自动行为,与 Yii 无关。如果你不希望数据库自动更新,应在建表时去掉 ON UPDATE,或改用 DATETIME 类型并由应用层完全控制。
否则可能出现:Yii 没设 updated_at,但数据库仍把它改了,而模型对象里还是旧值,造成数据不一致。











