thinkphp 6 已完全移除 auto/filter/validate 等旧机制,须改用修改器(如 setcreatetimeattr)、静态事件(如 onbeforeinsert,需手动绑定)或手动赋值;saveall() 和 where()->update() 等操作不触发模型逻辑。

自动完成在 ThinkPHP 5.1+ 中已废弃,别再配 auto 或 filter
ThinkPHP 6 完全移除了模型的 auto、filter、validate 等旧式自动处理机制;5.1 起就标记为废弃。你现在看到的文档或老教程里写的 _validate、_auto 数组,运行时不会生效,也不会报错——它就静静跳过。
常见错误现象:
– 字段始终没被赋值(比如 create_time 一直为 null)
– 调试发现 before_insert 回调根本没触发
– 模型 save() 后数据库字段和预期不符,但查不到哪里出问题
- ThinkPHP 5.1+ 必须用「事件回调」或「访问器/修改器」替代自动完成
- TP6 只保留
onBeforeInsert、onAfterUpdate等静态事件钩子,且需手动绑定 - 直接在
save()前手动赋值(如$model->update_time = date('Y-m-d H:i:s'))是最简单、最可控的方式
用修改器(mutator)处理字段写入前逻辑
这是目前最推荐的做法,适合对单个字段做格式化、默认值、加密等操作,且逻辑会随模型一起复用。
使用场景:
– 自动转小写(如 username)
– 密码字段自动哈希(password)
– 时间字段补全(create_time 为空时设为 now)
- 在模型类中定义
setCreateTimeAttr方法,方法名格式为set + 字段名首字母大写 + Attr - 该方法接收原始值(可能为 null),返回最终写入数据库的值
- 注意:修改器只在
save()/create()等写入操作中触发,where()->update()绕过所有模型逻辑
public function setCreateTimeAttr($value)
{
return $value ?: date('Y-m-d H:i:s');
}
onBeforeInsert 事件在 TP6 中怎么正确绑定
TP6 的模型事件不是自动注册的,必须显式调用 event() 方法绑定,否则回调永不执行。
常见错误现象:
– 写了 protected static function onBeforeInsert() 却没反应
– 在控制器里 new 模型后直接 save(),事件不触发
- 事件方法必须是
static,且命名严格为onBeforeInsert、onAfterUpdate等 - 必须在模型类加载后、首次使用前调用
self::event('before_insert', [static::class, 'onBeforeInsert']) - 更稳妥的做法是在模型的
init()静态方法里绑定(TP6 文档推荐)
protected static function init()
{
self::event('before_insert', function ($model) {
$model->create_time = date('Y-m-d H:i:s');
});
}
批量插入(saveAll)时自动处理容易漏掉的点
saveAll() 是个陷阱区:它内部走的是批量写入 SQL,不逐条实例化模型对象,因此所有基于实例的修改器、事件回调全部失效。
使用场景:
– 导入 Excel 数据
– 后台批量新增用户
– 接口接收数组并一次性存库
- 如果字段有默认值或需统一处理(如加时间戳、生成 UUID),必须提前在数据数组里赋值
- 不能依赖模型里的
setXxxAttr,因为saveAll([...])不会调用它们 - TP6 中可改用
Db::name('user')->insertAll($data),更透明,也避免模型层干扰
真正复杂的地方不在“怎么写”,而在“什么时候不走模型”——比如 where()->update()、insertAll()、事务中直接 DB 操作,这些路径下你精心写的修改器和事件,一个都不会动。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











