Yii中TimestampBehavior默认用time(),需数据库时间则禁用行为并在beforeSave中设new Expression('NOW()');用自定义时间可赋值模型属性并配置value回调为null;时区须PHP与MySQL统一。

Yii框架中,TimestampBehavior 默认使用 time()(即服务器当前时间)作为时间戳来源。若需指定其他时间源(例如数据库当前时间、自定义时间变量或特定字段值),不能仅靠行为配置完成,需结合重写或扩展方式实现。
使用数据库时间(如 NOW())作为时间源
当希望创建/更新时间由数据库生成(避免应用层与数据库时区不一致),应禁用 TimestampBehavior 的自动赋值,改用 ActiveRecord 的 beforeSave() 手动设置,并配合 SQL 函数:
- 在模型中关闭对应属性的自动填充(如移除
'createdAt'和'updatedAt'的TimestampBehavior配置) - 重写
beforeSave()方法,在插入或更新前将字段设为new Expression('NOW()')
示例:
use yii\db\Expression;
public function beforeSave($insert)
{
if ($insert) {
$this->created_at = new Expression('NOW()');
}
$this->updated_at = new Expression('NOW()');
return parent::beforeSave($insert);
}
使用自定义时间变量(如请求传入的时间)
若业务要求以客户端传递的时间、日志时间或其他外部时间为准,可在保存前主动赋值,确保该值优先于行为逻辑:
- 在控制器或服务层准备好时间戳(如
$customTime = strtotime('2024-01-01 12:00:00')) - 赋值给模型属性(如
$model->created_at = $customTime) - 确保
TimestampBehavior的value回调不覆盖它——可将其设为null或返回function () { return null; },让行为跳过自动填充
通过 value 回调动态指定时间源
TimestampBehavior 支持 value 配置项,接收闭包,可用于灵活控制时间来源:
- 返回
null表示不自动填充(交由其他逻辑处理) - 返回
time()、strtotime('yesterday')等 PHP 时间表达式 - 访问模型当前状态,例如:
function ($event) { return $this->custom_time ?: time(); }
配置示例:
public function behaviors()
{
return [
[
'class' => TimestampBehavior::class,
'createdAtAttribute' => 'created_at',
'updatedAtAttribute' => 'updated_at',
'value' => function ($event) {
// 优先使用模型已设置的 custom_timestamp,否则用当前时间
return $this->custom_timestamp ?: time();
},
],
];
}
注意时区一致性
无论选择哪种时间源,都需统一时区处理:
- PHP 层建议设置
date_default_timezone_set('Asia/Shanghai') - MySQL 需确认
time_zone设置与 PHP 一致(如+08:00),避免NOW()与time()结果偏差 - 若存储为 UTC,所有
value回调应返回time()并确保数据库字段类型为TIMESTAMP(自动按连接时区转换)


















