ThinkPHP:模型三大利器之二(修改器)
修改器是模型的三大利「器」之一,本篇我们来总结下修改器的用法,以及一些注意事项。
定义修改器
修改器的作用是在模型对象数据写入数据库之前进行一些必要的数据处理,修改器的标准定义如下:
public function setFieldNameAttr($value, $data) { // 对value值进行处理 data参数是当前全部数据 // 返回值就是实际要写入数据库的值 return $value; }
其中FieldName对应数据表的field_name字段(注意数据表字段的规范和修改器方法定义规范,否则会导致错误)。
原则上,每个修改器应当仅处理对应字段的数据,但在必要的情况下允许同时处理多个字段。
下面是一个例子
public function setBirthdayAttr($value, $data) { // 格式化生日数据 $birthday = strtotime($value); // 根据生日判断年龄 $age = getAgeByBirthday($birthday); // 赋值年龄数据 $this->setAttr('age', $age); return $birthday; } public function setAgeAttr($value,$data) { return floor($value); }
之所以使用setAttr方法是确保年龄赋值操作仍然可以走单独的修改器。如果你没有额外的修改器,那么也可以写成
public function setBirthdayAttr($value, $data) { // 格式化生日数据 $birthday = strtotime($value); // 根据生日判断年龄 $age = getAgeByBirthday($birthday); // 赋值年龄数据 $this->data['age'] = $age; return $birthday; }
注意一定不能写成
$this->age = $age;
因为在模型内部进行数据对象的赋值,会因为和模型内部属性混淆而导致不可预知的后果。
如果你在某个修改器中可能会对其它字段进行修改,务必记得你需要额外修改的字段修改器必须已经经过赋值操作(或者已经触发过修改器)。
如何调用
修改器方法不需要手动调用,按照定义规范定义好后,系统会在下面的情况下自动调用:
·模型对象赋值;
·调用模型的data方法,并且第二个参数传入true;
·调用模型的save方法,并且传入数组数据;
·显式调用模型的setAttr方法;
·定义了该字段的自动完成;
例如User模型定义了setPasswordAttr修改器方法。
public function setPasswordAttr($value, $data) { return md5($value); }
当下面这样使用的时候,保存到数据库的password字段的值就会变成md5('think')后的值。
$user = User::get(1); $user->password = 'think'; $user->save();
如果你在一些情况下,不希望使用修改器而是想要手动控制数据,可以尝试使用下面的方法。
$user = User::get(1); $user->data('password', md5('think')); $user->save();
这个时候就不会经过修改器处理。
避免冲突
很多开发者喜欢给修改器定义自动完成auto(包括insert和update)。
protected $auto = ['password'];
这在V5.1.27版本之前是一个看似聪明却非常致命的错误,要尽量避免,因为根据我们之前给出的修改器触发条件,会导致该修改器被执行两次。这会是一个灾难性的错误,将导致所有的用户注册后都无法正常登录。
解决办法取消password字段的自动完成设置,因为修改器会在每次赋值的时候自动触发,如果没有赋值说明密码没有被修改,也谈不上自动完成。
自动完成的字段通常是不在表单里面的字段,一般是由系统自动处理的字段。
V5.1.27版本改进了这个问题,所有的修改器只允许执行一次,上面的问题就不复存在了。但好像又带来了一个新的问题,很多时候,你也许想在模型的事件中对数据进行修改。
User::beforeUpdate(function($user) { $user->password = md5('think'); });
会发现,在模型beforeUpdate事件中,数据的值怎么都修改不了,原因是模型的修改器之前在第一次赋值的时候已经执行了,第二次再赋值的时候已经无效了(不会再执行)。
解决办法就是我前面提过的使用data方法不调用修改器进行数据赋值操作。
User::beforeUpdate(function($user) { $user->data('password', md5('think')); });
当然,更好的建议是规划好修改器、自动完成和模型事件的数据处理机制,不要对一个字段同时使用多重机制修改数据,并且写入数据库的数据应该并且只有修改器这一个途径进行数据修改操作。
类型自动转化
如果你的修改器仅仅是对数据做类型转换处理的话,可以无需定义修改器,而是直接定义字段类型就可以了。
public function setScoreAttr($value, $data) { return (float) $score; }
上面的修改器方法可以直接改成
protected $type = [ 'score' => 'float', ];
如果你同时对一个字段定义了修改器和类型的话,修改器是优先的。
类型定义不仅能定义简单的数据类型,还有一些额外的用途,例如:json 类型、array类型和object 类型会进行JSON序列化,serialize类型则会把数据进行serialize序列化。
PHP中文网,有大量免费的ThinkPHP入门教程,欢迎大家学习!
本文转自:https://blog.thinkphp.cn/817548
以上是ThinkPHP:模型三大利器之二(修改器)的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

想象一下,一个人工智能模型,不仅拥有超越传统计算的能力,还能以更低的成本实现更高效的性能。这不是科幻,DeepSeek-V2[1],全球最强开源MoE模型来了。DeepSeek-V2是一个强大的专家混合(MoE)语言模型,具有训练经济、推理高效的特点。它由236B个参数组成,其中21B个参数用于激活每个标记。与DeepSeek67B相比,DeepSeek-V2性能更强,同时节省了42.5%的训练成本,减少了93.3%的KV缓存,最大生成吞吐量提高到5.76倍。DeepSeek是一家探索通用人工智

本月初,来自MIT等机构的研究者提出了一种非常有潜力的MLP替代方法——KAN。KAN在准确性和可解释性方面表现优于MLP。而且它能以非常少的参数量胜过以更大参数量运行的MLP。比如,作者表示,他们用KAN以更小的网络和更高的自动化程度重现了DeepMind的结果。具体来说,DeepMind的MLP有大约300,000个参数,而KAN只有约200个参数。KAN与MLP一样具有强大的数学基础,MLP基于通用逼近定理,而KAN基于Kolmogorov-Arnold表示定理。如下图所示,KAN在边上具

波士顿动力Atlas,正式进入电动机器人时代!昨天,液压Atlas刚刚「含泪」退出历史舞台,今天波士顿动力就宣布:电动Atlas上岗。看来,在商用人形机器人领域,波士顿动力是下定决心要和特斯拉硬刚一把了。新视频放出后,短短十几小时内,就已经有一百多万观看。旧人离去,新角色登场,这是历史的必然。毫无疑问,今年是人形机器人的爆发年。网友锐评:机器人的进步,让今年看起来像人类的开幕式动作、自由度远超人类,但这真不是恐怖片?视频一开始,Atlas平静地躺在地上,看起来应该是仰面朝天。接下来,让人惊掉下巴

ThinkPHP 拥有多个版本,针对不同 PHP 版本而设计。主要版本包括 3.2、5.0、5.1 和 6.0,而次要版本用于修复 bug 和提供新功能。当前最新稳定版本为 ThinkPHP 6.0.16。在选择版本时,需考虑 PHP 版本、功能需求和社区支持。建议使用最新稳定版本以获得最佳性能和支持。

目标检测在自动驾驶系统当中是一个比较成熟的问题,其中行人检测是最早得以部署算法之一。在多数论文当中已经进行了非常全面的研究。然而,利用鱼眼相机进行环视的距离感知相对来说研究较少。由于径向畸变大,标准的边界框表示在鱼眼相机当中很难实施。为了缓解上述描述,我们探索了扩展边界框、椭圆、通用多边形设计为极坐标/角度表示,并定义一个实例分割mIOU度量来分析这些表示。所提出的具有多边形形状的模型fisheyeDetNet优于其他模型,并同时在用于自动驾驶的Valeo鱼眼相机数据集上实现了49.5%的mAP

特斯拉机器人Optimus最新视频出炉,已经可以在厂子里打工了。正常速度下,它分拣电池(特斯拉的4680电池)是这样的:官方还放出了20倍速下的样子——在小小的“工位”上,拣啊拣啊拣:这次放出的视频亮点之一在于Optimus在厂子里完成这项工作,是完全自主的,全程没有人为的干预。并且在Optimus的视角之下,它还可以把放歪了的电池重新捡起来放置,主打一个自动纠错:对于Optimus的手,英伟达科学家JimFan给出了高度的评价:Optimus的手是全球五指机器人里最灵巧的之一。它的手不仅有触觉

ThinkPHP Framework 的本地运行步骤:下载并解压 ThinkPHP Framework 到本地目录。创建虚拟主机(可选),指向 ThinkPHP 根目录。配置数据库连接参数。启动 Web 服务器。初始化 ThinkPHP 应用程序。访问 ThinkPHP 应用程序 URL 运行。

FP8和更低的浮点数量化精度,不再是H100的“专利”了!老黄想让大家用INT8/INT4,微软DeepSpeed团队在没有英伟达官方支持的条件下,硬生生在A100上跑起FP6。测试结果表明,新方法TC-FPx在A100上的FP6量化,速度接近甚至偶尔超过INT4,而且拥有比后者更高的精度。在此基础之上,还有端到端的大模型支持,目前已经开源并集成到了DeepSpeed等深度学习推理框架中。这一成果对大模型的加速效果也是立竿见影——在这种框架下用单卡跑Llama,吞吐量比双卡还要高2.65倍。一名
