yii2.0.27中不同模型可独立配置时间戳行为,关键在于各模型单独定义behaviors()方法并适配自身字段;字段不存在时行为静默跳过,rest场景需在rules()中声明时间戳字段为safe或required。

Yii2.0.27 中,不同模型可以独立配置时间戳行为,关键在于**不共用同一份 behavior 配置**,而是每个模型按需声明自己的 behaviors() 方法,并适配各自的数据表字段和业务逻辑。
各模型单独定义 TimestampBehavior
每个 ActiveRecord 模型都可覆盖 behaviors() 方法,指定属于自己的时间戳字段名、触发时机和值生成方式。例如:
- User 表有
created_at和updated_at(datetime 类型) - Log 表只有
created_time(int 时间戳),无需更新时间 - Setting 表使用
ctime和mtime,且要求数据库写入NOW()
对应写法示例:
class User extends ActiveRecord
{
public function behaviors()
{
return [
[
'class' => TimestampBehavior::className(),
'createdAtAttribute' => 'created_at',
'updatedAtAttribute' => 'updated_at',
'value' => date('Y-m-d H:i:s'),
],
];
}
}
class Log extends ActiveRecord
{
public function behaviors()
{
return [
[
'class' => TimestampBehavior::className(),
'createdAtAttribute' => 'created_time',
'updatedAtAttribute' => false, // 禁用更新时间
'value' => time(),
],
];
}
}
class Setting extends ActiveRecord
{
public function behaviors()
{
return [
[
'class' => TimestampBehavior::className(),
'createdAtAttribute' => 'ctime',
'updatedAtAttribute' => 'mtime',
'value' => new Expression('NOW()'), // 交由 MySQL 执行
],
];
}
}
字段存在性不影响行为启用
Yii2.0.27 的 TimestampBehavior 在执行时会检查目标字段是否真实存在于当前模型的 attributes 列表中。若字段不存在(如误写为 create_at),行为不会报错,也不会赋值——它会静默跳过该字段。因此,即使多个模型继承自同一个基类,只要各自 behaviors() 中指定的字段名与本表结构一致,就不会互相干扰。
不需要为每个模型额外写防御逻辑,也不必担心“通用基类里写了 updated_at,但 Comment 表没这个字段就崩掉”这类问题。
REST 场景下必须确保字段可加载
在 RESTful 接口(如 ActiveController)中,时间戳字段默认不进入安全属性列表,导致 load() 不加载它们,进而使行为无法触发。解决方法是在每个模型的 rules() 中显式声明:
-
['created_at', 'updated_at', 'safe']—— 最简方案 - 或更严谨地:
['created_at', 'updated_at', 'required', 'on' => ['default', 'create']]配合场景控制
注意:不能只靠数据库默认值或 DEFAULT CURRENT_TIMESTAMP,因为 Yii 模型层需要感知字段变更才能正确参与事件流。
避免手动赋值覆盖行为逻辑
一旦启用了 TimestampBehavior,就应避免在控制器或模型中直接写:
$model->updated_at = date('Y-m-d H:i:s');
这会导致行为被绕过,时间戳更新逻辑分散,后期难以维护。所有时间管理应收敛到 behavior 配置中,保持单一可信源。











