使用 catchAdmin(tp6 框架)二次开发时发现,ThinkPHP6 修改器似乎没有触发,不起作用。

定义的 tp6 修改器
定义的 tp6 修改器

在 tp6 的官方文档中 修改器 一节明确指出了以下四种触发修改器的情况:

  • 模型对象赋值;
  • 调用模型的 data 方法,并且第二个参数传入 true;
  • 调用模型的 save 方法,并且传入数据;
  • 显式调用模型的 setAttr 方法;

因为 save 的存在,正常保存数据的时候就会触发修改器。修改器这个概念跟 Java 中的 setter 方法基本相同,就是修改模型的字段值,只不过在 tp6 里属于自动触发。只要定义了相关的修改器,在对数据进行操作(插入,更新)的时候就会触发。

从官方文档中 修改器 下面的评论里也能看出来,这种修改器不触发的问题不是个例。

一开始想用 xdebug 通过断点调试看一下到底是哪一步出现了问题,后因直接加断点无效,就懒得去弄,直接看 tp6 源码了。

vendor\topthink\think-orm\src\model\concern\Attribute.php

tp6 修改器源码
tp6 修改器源码

tp6 修改器源码
tp6 修改器源码

仔仔细细地检查了一遍,发现并没有什么问题。后检查输入参数时,结合修改器的源码终于恍然大悟: Request 请求参数中不存在 id_numberfrom 两个参数,这两个参数是后台生成的。而直接将 Request 请求参数传递到 save(),进而传递到 setAttrs() 中时,因为 $data 中没有这两个参数 key 值,在遍历调用 setAttr() 时也没有设置这两个参数的值,自然也无从调用修改器了。

所以,简单的解决方法就是 array_merge($request->post(), ['id_number'=>'','from'=>'']),或者前端提交参数时,设置这两项空值。

建议 ThinkPHP6 的开发人员根据 模型字段 去匹配调用修改器,而不是输入参数。