搜索
首页php框架ThinkPHPThinkPHP:模型三大利器之三(获取器)

ThinkPHP:模型三大利器之三(获取器)

定义获取器

获取器的作用是对模型对象的(原始)数据做出自动处理。一个获取器对应模型的一个特殊方法(该方法必须为public类型),方法命名规范为:

getFieldNameAttr

FieldName为数据表字段的驼峰转换或者你数据表不存在的字段(注意理解后面这句话),下面是一个典型的获取器定义:

<?php
namespace app\index\model;
use think\Model;
class User extends Model
{
    public function getUserTypeAttr($value, $data)
    {
        $type = [0 => &#39;普通&#39;, 1 => &#39;VIP&#39;, 2 => &#39;黄金&#39;, 3 => &#39;白金&#39;, 4 => &#39;钻石&#39;];
        return $type[$value];
    }
}

你需要给每一个需要输出转换处理的数据字段定义一个对应的获取器,但获取器的字段名不一定要和数据表的字段名一致,例如我希望给user_type字段定义一个名为getTypeAttr的获取器也是允许的,但要注意这个时候传入获取器的第一个参数肯定是没有值(因为没有对应的数据表字段数据),只能通过第二个参数获取你需要的数据。

<?php
namespace app\index\model;
use think\Model;
class User extends Model
{
    public function getTypeAttr($value, $data)
    {
        $type = [0 => &#39;普通&#39;, 1 => &#39;VIP&#39;, 2 => &#39;黄金&#39;, 3 => &#39;白金&#39;, 4 => &#39;钻石&#39;];
        return $type[$data[&#39;user_type&#39;]];
    }
}

当然更为严谨的情况下,你还需要判断下是否存在$data['user_type'],这个暂且略过。

注意第二个参数的data数据,可能本身已经经过了获取器的处理(如果你定义了相关的获取器的话)。

为什么要定义一个和数据报字段不一致的获取器呢?最明显的好处可以区分不同的字段获取原始数据和处理过的数据。事实上,有很多理由可以让你定义一些数据表不存在的字段获取器,这恰恰是获取器的魅力所在。

看的出来获取器定义本身没什么难度,关键在于方法里面的获取逻辑,这是实际应用中最需要关注的。

调用获取器

定义获取器之后会在下列情况自动触发:

·模型的数据对象取值操作(例如$model->field_name);

·模型的序列化输出操作(例如$model->toArray()或toJson());

·显式调用getAttr方法(例如$model->getAttr('field_name'));

前面两种其实最终都是调用最后一种来实现的,最关键的是要理解第一种。模型对象取值的时候一般都是通过下面的方式:

$user = User::get(1);
echo $user->name;
echo $user->user_type;

当我们使用上面的方式进行模型对象数据获取或者在模板输出的时候事实上都会按照下面的顺序来检测和获取数据。

·第1步——如果查询结果包含该字段数据,取回原始数据,否则并进入第2步;

·第2步——检查是否定义该字段的获取器(包括动态获取器),如果有,则调用获取器返回结果,没有则进入第3步;

·第3步——检查是否定义了字段的类型转换,有则进行转换处理并返回结果,没有则进入第4步;

·第4步——如果是系统的时间字段,则自动进行时间格式化处理并返回结果,否则进入第5步;

·第5步——如果第1步检查的时候不包含该字段数据,则检查是否存在关联属性定义,有则通过关联关系获取数据并返回结果,否则抛出属性未定义的异常。

上面的这五个步骤的详细代码,如果你有兴趣的可以直接参考think\model\concern\Attribute的getAttr方法代码。

简单来说,当你获取$user->user_type的时候都会去检查是否定义了相关的获取器,而不管user_type字段是否是一个真实的数据表字段。

但很多情况下,你不会一个个去获取模型数据,而是把整个模型数据返回给客户端或者模板。

public function index()
{
    $user = User::get(1);
    return json($user);
}

在这种情况下,其实就是在响应输出的时候进行了模型的toJson处理。

有一点至关重要,如果你的获取器定义了非数据表的字段,是不会自动输出的,必须通过append方法追加额外属性(并且支持追加关联模型属性)。

如果我们定义了一个type属性的获取器(假设这并不是一个真实的数据表字段),那么需要使用下的方式才能正常输出(否则你可能只有user_type数据):

public function index()
{
    $user = User::get(1);
    return json($user->append([&#39;type&#39;]));
}

如果你是使用toArray的话,处理方式相同。

如果是数据集查询的话,一样可以使用append方法统一追加额外字段。

public function index()
{
    $users = User::all();
    return json($users->append([&#39;type&#39;]));
}

除了append方法之外,我们还支持用hidden方法临时隐藏一些数据。

获取原始数据

有些情况下,除了要获取处理过的数据外,还需要获取原始数据以便应对不同的需求。

如果你的获取器都是用的区分于实际数据表字段的额外属性字段,那么这个问题本身已经解决了。所以我们主要讨论的是当你的获取器属性和数据表字段一致的情况下,该如何获取原始数据。

一个最简单的办法是使用getData方法:

$user = User::get(1);
// 获取user_type获取器数据
echo $user->user_type;
// 获取原始的user_type数据
echo $user->getData(&#39;user_type&#39;);
// 获取全部原始数据
dump($user->getData());

动态获取器

前面我们提到过动态获取器的概念,动态获取器就是不需要在模型类里面定义获取器方法,而是在查询的时候使用闭包来定义一个字段的获取器对数据进行统一的处理。

User::withAttr(&#39;name&#39;, function($value, $data) {
return strtolower($value);
})->select();

如果你需要定义多个动态获取器,多次调用withAttr方法就行。

动态获取器的意义除了可以不用在模型里面定义获取器方法之外,还可以起到覆盖已经定义的获取器的作用,并且动态获取器可以支持Db类操作,弥补了Db操作不能使用获取器的缺憾,具体就看自己的需求来选择了。

Db::name(&#39;user&#39;)->withAttr(&#39;name&#39;, function($value, $data) {
return strtolower($value);
})->select();

总结

无论是获取器,还是之前提的修改器、搜索器,其作用无非是把你的模型工作细化和拆分,这样代码和逻辑也会更清晰,可维护性也大大增强,至于性能,从来不是模型首先考虑的。

PHP中文网,有大量免费的ThinkPHP入门教程,欢迎大家学习!

本文转自:https://blog.thinkphp.cn/825350

以上是ThinkPHP:模型三大利器之三(获取器)的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:ThinkPHP官网。如有侵权,请联系admin@php.cn删除
ThinkPHP内置测试框架的关键功能是什么?ThinkPHP内置测试框架的关键功能是什么?Mar 18, 2025 pm 05:01 PM

本文讨论了ThinkPHP的内置测试框架,突出了其关键功能(例如单元和集成测试),以及它如何通过早期的错误检测和改进的代码质量来增强应用程序可靠性。

如何使用ThinkPHP来构建实时股票市场数据源?如何使用ThinkPHP来构建实时股票市场数据源?Mar 18, 2025 pm 04:57 PM

文章讨论了使用ThinkPHP进行实时股票市场数据提要,重点是设置,数据准确性,优化和安全措施。

在无服务器体系结构中使用ThinkPHP的关键注意事项是什么?在无服务器体系结构中使用ThinkPHP的关键注意事项是什么?Mar 18, 2025 pm 04:54 PM

本文讨论了在无服务器体系结构中使用ThinkPHP的关键注意事项,专注于性能优化,无状态设计和安全性。它突出了诸如成本效率和可扩展性之类的收益,但也应对挑战

如何在ThinkPHP微服务中实现服务发现和负载平衡?如何在ThinkPHP微服务中实现服务发现和负载平衡?Mar 18, 2025 pm 04:51 PM

本文讨论了在ThinkPHP微服务中实施服务发现和负载平衡,重点是设置,最佳实践,集成方法和推荐工具。[159个字符]

ThinkPHP依赖性注入容器的高级功能是什么?ThinkPHP依赖性注入容器的高级功能是什么?Mar 18, 2025 pm 04:50 PM

ThinkPHP的IOC容器提供了高级功能,例如懒惰加载,上下文绑定和方法注入PHP App中有效依赖性管理的方法。Character计数:159

如何使用ThinkPHP来构建实时协作工具?如何使用ThinkPHP来构建实时协作工具?Mar 18, 2025 pm 04:49 PM

本文讨论了使用ThinkPHP来构建实时协作工具,重点关注设置,Websocket集成和安全性最佳实践。

使用ThinkPHP来构建SaaS应用程序的主要好处是什么?使用ThinkPHP来构建SaaS应用程序的主要好处是什么?Mar 18, 2025 pm 04:46 PM

ThinkPHP具有轻巧的设计,MVC架构和可扩展性。它通过各种功能提高可扩展性,加快开发并提高安全性。

如何使用ThinkPHP和RabbitMQ构建分布式任务队列系统?如何使用ThinkPHP和RabbitMQ构建分布式任务队列系统?Mar 18, 2025 pm 04:45 PM

本文概述了使用ThinkPhp和RabbitMQ构建分布式任务队列系统,重点是安装,配置,任务管理和可扩展性。关键问题包括确保高可用性,避免常见的陷阱,例如不当

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
4 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
4 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
4 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
1 个月前By尊渡假赌尊渡假赌尊渡假赌

热工具

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。