在 Yii2.0.40 中,仅自动填充 created_at 而不干扰 updated_at,需在 behaviors() 中精准配置 attributes:只映射 ActiveRecord::EVENT_BEFORE_INSERT => ['created_at'],完全不配置 EVENT_BEFORE_UPDATE,并确保 value 类型与数据库字段(INT/DATETIME)匹配。

在 Yii2.0.40 中,单独指定新增记录的时间戳(即只自动填充 created_at,不干扰 updated_at 或其他字段),关键在于精准配置 TimestampBehavior 的触发时机和字段映射,避免默认行为“一锅端”。
明确只在插入时设置 created_at
默认行为会同时给 created_at 和 updated_at 赋值,但你可以覆盖它,只保留插入逻辑:
- 在模型的
behaviors()方法中显式声明attributes键 - 仅将
created_at映射到ActiveRecord::EVENT_BEFORE_INSERT - 完全不为
EVENT_BEFORE_UPDATE配置任何字段(这样updated_at就不会被行为自动改写)
示例代码:
public function behaviors()
{
return [
[
'class' => TimestampBehavior::className(),
'attributes' => [
ActiveRecord::EVENT_BEFORE_INSERT => ['created_at'],
// EVENT_BEFORE_UPDATE => [] ← 留空或直接不写,确保 updated_at 不被自动更新
],
'value' => time(), // 或用 function() { return date('Y-m-d H:i:s'); } 匹配 datetime 类型
],
];
}
确保 updated_at 不被意外覆盖
如果你的表里也有 updated_at 字段,但希望它仅由业务逻辑手动更新(比如控制器中赋值),就必须防止行为介入:
- 不要把
updated_at写进attributes的任意事件中 - 检查模型的
rules():确认updated_at没有被设为required,否则可能因验证失败导致保存中断 - 如果使用 RESTful 接口,注意
load()是否把updated_at当作安全属性加载——若不需要它参与自动更新,就别让它进规则列表
适配数据库字段类型
时间戳值类型必须和数据库列匹配,否则存入为 0 或 NULL:
- 字段是
INT(Unix 时间戳)→'value' => time() - 字段是
DATETIME或TIMESTAMP→'value' => function() { return date('Y-m-d H:i:s'); } - MySQL 中也可用
'value' => new Expression('NOW()'),但需确保迁移时字段允许 NULL 或有默认值,且行为绑定在beforeInsert阶段生效
验证是否生效
最直接的方式是写个简单测试:
- 新建一条记录,dump 查看
$model->created_at是否已赋值 - 再调用
$model->save()更新同一条记录,检查created_at值是否保持不变 - 查看数据库实际写入值,确认没有被二次覆盖


















