thinkphp 6 中 _auto 已彻底移除,自动时间写入需设 protected $autowritetimestamp = true 并配合 $createtime/$updatetime 字段名及 $readonly,且仅在模型方法(如 save)中生效。

ThinkPHP 模型的自动完成(包括时间字段写入)在 5.1+ 版本中已废弃,TP6 彻底移除 $_auto;你现在配了也白配,不会触发。
为什么 $_auto 配了但 create_time 还是 null
因为 $_auto 是 ThinkPHP 3.x / 5.0 的旧机制,5.1 起标记为废弃,6.x 直接删了。你看到的文档若还在教 array('create_time', 'date', 1, 'function'),说明它过时了。
- 调用
Db::table()->insert()或where()->update()时,模型层完全不走,$_auto更不可能生效 -
save()和create()也不再解析$_auto数组,调试时断点打在before_insert里根本进不去 - 错误现象典型:数据库字段存在、类型正确、模型里写了
$_auto,但插入后仍是NULL或0000-00-00 00:00:00
$autoWriteTimestamp = true 才是当前唯一有效的开关
这个属性控制的是「创建/更新时间字段」的自动写入,和 $_auto 完全无关。它只对 save()、create()、update() 等模型方法起作用。
- 必须显式设置:
protected $autoWriteTimestamp = true;,默认是false - 字段名要匹配:
protected $createTime = 'create_time';和protected $updateTime = 'update_time';,不能写成createTime(驼峰)或大小写混用 - 数据库字段类型推荐
DATETIME或TIMESTAMP;若用INT,必须加protected $type = ['create_time' => 'integer'];,否则会存成字符串 -
$readonly = ['create_time']要配上,否则更新时可能把create_time也覆盖掉
更新时 update_time 没变,不是 bug,是设计逻辑
ThinkPHP 只在「检测到数据实际变更」时才更新 update_time,不是每次 save() 都刷。比如 $user->save(['name' => '张三']),而数据库里 name 原值就是 张三,那 update_time 就不动。
- 这个判断发生在模型内部的
isUpdate()流程中,依赖$this->origin(原始数据)与$this->data(新数据)比对 - 用
where()->update()绕过模型,update_time永远不会自动更新 - 如果业务上要求“只要调用就更新”,得手动赋值:
$user->update_time = date('Y-m-d H:i:s');,再save()
状态变更时间(如 disable_time)必须手写逻辑
ThinkPHP 不支持一个字段记录多个状态时间点,也不能靠 $updateTime 复用。停用、启用、冻结等操作的时间,得在模型层自己处理。
- 推荐在
beforeWrite钩子里做:if ($this->data['status'] == 0 && $this->origin['status'] == 1) { $this->data['disable_time'] = date('Y-m-d H:i:s'); } -
$this->origin仅在更新操作中可用,新增时为空,需加if ($this->isUpdate())判断 - 别在控制器里写时间赋值——状态含义(比如
2是冻结、3是注销)只有模型知道,放错层会导致逻辑散落、难维护 - 修改器(
setDisableTimeAttr)不适合这种「条件性写入」,它无上下文,看不到旧值
最易被忽略的一点:所有自动写入逻辑都依赖「走模型方法」。一旦用了 Db::name('user')->insert() 或 Db::name('user')->where(...)->update(),整个时间字段链就断了——连 $autoWriteTimestamp 都没机会执行。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











