tp6中唯一可靠的自动时间字段写入开关是$autowritetimestamp,$_auto和$auto已彻底移除;时间字段需显式配置createtime/updatetime,非标准字段须用修改器或before_write事件处理。

$autoWriteTimestamp 是当前唯一可靠的自动时间字段写入开关,$_auto 和 $auto 在 TP6 中已彻底移除,配了也不生效。
TP6 里 $_auto 为什么完全不触发
ThinkPHP 6 删除了所有旧式自动完成机制,包括 $_auto、$auto、$insert、$update。哪怕你照着 TP3/5 文档写全了规则,模型 save() 时也不会执行,也不会报错——直接跳过。
- 典型错误现象:
create_time字段始终为NULL或0000-00-00 00:00:00,断点打在before_insert里根本进不去 -
Db::table()->insert()、where()->update()等原生查询完全不走模型层,自动完成天然失效 - TP5.1+ 已废弃
create(),TP6 彻底删除;继续用会触发Deprecated警告甚至报错
时间字段必须用 $autoWriteTimestamp 配置
这是 TP6 唯一支持的自动时间写入方式,但字段名、类型、时机都必须严格匹配。
- 启用开关:
protected $autoWriteTimestamp = true;(默认是false) - 字段名要显式声明:
protected $createTime = 'create_time';和protected $updateTime = 'update_time';,不能写成created_at或驼峰 - 数据库字段类型推荐
DATETIME;若用INT,必须加protected $type = ['create_time' => 'integer'];,否则存成字符串 -
$readonly = ['create_time']强烈建议配上,否则更新时可能把create_time覆盖掉
业务字段(如 create_by、ip、fingerprint)得靠修改器
所有非标准时间字段,都不能依赖自动完成,必须用 setXxxAttr() 修改器或 before_write 事件手动处理。
- 字段名
create_by→ 方法名必须是setCreateByAttr(),不是setCreatebyAttr或setCreatedByAttr - 修改器接收两个参数:
function setFingerprintAttr($value, $data),其中$data是完整待写入数组,可安全读取$data['name']、$data['email'] - 别在修改器里调
$this->name—— 此时模型属性可能还没赋值,应从$data取 - IP、User-Agent 等需清洗的字段,应在修改器里做
filter_var($ip, FILTER_VALIDATE_IP)和substr($ua, 0, 200)截断
容易被忽略的执行时机陷阱
自动填充不是“写进去就完事”,它只在特定流程中触发,且顺序敏感。
-
$model->save(['name' => 'x'])直接跳过所有模型逻辑,setXxxAttr和$autoWriteTimestamp全部失效;必须改用$model->data(['name' => 'x'])->save() - 修改器和
$autoWriteTimestamp都只对save()、create()生效;Db::name()->insert()完全绕过 - 软删除字段
delete_time不属于$autoWriteTimestamp范围,得在before_delete事件里手动赋值 - 多个修改器之间可能互相干扰,比如
setFingerprintAttr里读$this->ip,而setIpAttr又依赖$this->user_agent,容易触发无限递归
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











