thinkphp6模型修改器仅在save、create、update等模型写入生命周期中触发,直接赋值、db类操作、insert方法、批量update及未调用save均不触发;需确保方法命名规范(set+字段名首字母大写+attr)、继承think\model、字段非只读/未被allowfield过滤。

ThinkPHP6模型修改器不触发,多数情况是写法正确但调用路径错了——它只在模型的save、create、update等写入生命周期中生效,直接赋值或Db类操作完全不会触发。
确认修改器命名和定义位置
修改器方法名必须是set+字段名首字母大写+Attr,例如数据库字段为password,方法名只能是user_name,则必须写成_setAttr写法在TP6中已彻底弃用,写了也静默失效。
模型类必须继承think\Model,不能误用think\db\Model——后者是查询构建器基类,不支持修改器。
方法体只需接收一个参数$value,TP6.1+默认不再自动传入$data数组;若需依赖其他字段,改用beforeWrite事件更稳妥。
必须走模型写入流程才能触发
✅ 有效触发方式:
方法一:先赋值再save()
$user = new User(); $user->password = '123'; $user->save();
方法二:用create()一次性写入
User::create(['password' => '123']);
方法三:用save()传参写入
$user = new User(); $user->save(['password' => '123']);
⚠️ 注意:【data() 方法绕过所有修改器逻辑】,除非显式加true参数,否则$user->data(['password' => '123'])->save()完全不触发修改器。
排查字段是否被过滤或不可写
第一步:检查该字段是否在protected $readonly或protected $disuse数组中——若在其中,save时会直接跳过,修改器自然不执行。
第二步:确认save()调用时没传allowField白名单,比如$user->allowField(['id', 'name'])->save(),如果password不在白名单里,它会被彻底忽略。
第三步:查看数据库表结构,确认字段真实存在且类型可写;若字段设为GENERATED ALWAYS AS(计算列),TP6无法写入,save()会静默跳过该字段。
绝对不触发修改器的操作
① 直接使用Db::name('user')->insert(['password' => '123'])——这是原生查询构建器操作,完全绕过模型层。
② 调用$model->insert($data)——底层走Query类,跳过模型save()生命周期。
③ 使用批量更新User::where()->update(['password' => '123'])——不创建单个模型实例,不走任何模型钩子。
④ 仅赋值不调用save():$user->password = '123';这句本身什么都不会发生,修改器不会因赋值而激活。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











