thinkphp6模型时间戳不更新需同时满足四条件:启用开关(protected $autowritetimestamp = true)、字段名映射(如protected $createtime = 'create_time')、调用save()等主动写入方法、数据库存在对应datetime/timestamp字段;缺一不可。

ThinkPHP6模型时间戳不更新,不是代码漏写了save(),而是自动写入机制没对齐——启用开关、字段名映射、调用方式、数据库结构这四者必须全部到位,缺一不可。
检查模型配置是否完整启用
TP6默认完全关闭自动时间戳,光写$autoWriteTimestamp = true不够,必须三行同时存在且全为protected:
-
protected $autoWriteTimestamp = true;(仅控制“是否启用”,不是格式) -
protected $createTime = 'create_time';(字段名必须和数据库列名完全一致,含大小写、下划线) -
protected $updateTime = 'update_time';(若字段叫updated_at,这里就得写'updated_at')
注意:TP6不认_autoWriteTimestamp(TP3/4写法)或$autoWriteTimestamp = 'datetime'(TP5写法),这些在TP6中无效或被忽略。
确认数据库字段真实存在且类型匹配
自动写入的前提是字段已建好。执行DESCRIBE your_table;确认:
-
create_time和update_time字段确实存在 - 字段类型为
DATETIME或TIMESTAMP(推荐);若用INT存时间戳,必须额外加:protected $type = ['create_time' => 'integer', 'update_time' => 'integer'];
字段名写错、类型不匹配,框架会静默跳过,不报错也不提示。
验证调用方式是否触发自动逻辑
自动时间戳只在模型的save()、data()->save()等主动写入方法中生效:
-
Db::table('user')->insert([...])→ 不触发 -
User::where('id', 1)->update(['name' => 'x'])→ 不触发 -
$user->isUpdate(true)->save()→ 只写updateTime,但前提是主键已赋值;若$user->id为空,它会当成新增,却因isUpdate(true)跳过createTime - 手动在数据里传了
'update_time' => time()→ 直接覆盖自动逻辑
排查是否被字段白名单过滤
这是最隐蔽的坑。用了allowField()却没把时间字段加进去,它们就被静默丢弃:
-
$user->allowField(true)->save($data)→ 要求$data数组里不能有create_time等字段,否则会被过滤 -
$user->allowField(['name', 'email'])->save($data)→create_time和update_time不在白名单,直接消失 - 临时测试可去掉所有字段限制:
$user->name = 'test'; $user->save();
调试时可在save()前加dump($user->getData());,看时间字段是否已生成并存在。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











