定义获取器
获取器的作用是对模型对象的(原始)数据做出自动处理。一个获取器对应模型的一个特殊方法(该方法必须为public类型),方法命名规范为:
getFieldNameAttr
FieldName为数据表字段的驼峰转换或者你数据表不存在的字段(注意理解后面这句话),下面是一个典型的获取器定义:
<?php namespace app\index\model; use think\Model; class User extends Model { public function getUserTypeAttr($value, $data) { $type = [0 => '普通', 1 => 'VIP', 2 => '黄金', 3 => '白金', 4 => '钻石']; 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 => '普通', 1 => 'VIP', 2 => '黄金', 3 => '白金', 4 => '钻石']; return $type[$data['user_type']]; } }
当然更为严谨的情况下,你还需要判断下是否存在$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(['type'])); }
如果你是使用toArray的话,处理方式相同。
如果是数据集查询的话,一样可以使用append方法统一追加额外字段。
public function index() { $users = User::all(); return json($users->append(['type'])); }
除了append方法之外,我们还支持用hidden方法临时隐藏一些数据。
获取原始数据
有些情况下,除了要获取处理过的数据外,还需要获取原始数据以便应对不同的需求。
如果你的获取器都是用的区分于实际数据表字段的额外属性字段,那么这个问题本身已经解决了。所以我们主要讨论的是当你的获取器属性和数据表字段一致的情况下,该如何获取原始数据。
一个最简单的办法是使用getData方法:
$user = User::get(1); // 获取user_type获取器数据 echo $user->user_type; // 获取原始的user_type数据 echo $user->getData('user_type'); // 获取全部原始数据 dump($user->getData());
动态获取器
前面我们提到过动态获取器的概念,动态获取器就是不需要在模型类里面定义获取器方法,而是在查询的时候使用闭包来定义一个字段的获取器对数据进行统一的处理。
User::withAttr('name', function($value, $data) { return strtolower($value); })->select();
如果你需要定义多个动态获取器,多次调用withAttr方法就行。
动态获取器的意义除了可以不用在模型里面定义获取器方法之外,还可以起到覆盖已经定义的获取器的作用,并且动态获取器可以支持Db类操作,弥补了Db操作不能使用获取器的缺憾,具体就看自己的需求来选择了。
Db::name('user')->withAttr('name', function($value, $data) { return strtolower($value); })->select();
总结
无论是获取器,还是之前提的修改器、搜索器,其作用无非是把你的模型工作细化和拆分,这样代码和逻辑也会更清晰,可维护性也大大增强,至于性能,从来不是模型首先考虑的。
PHP中文网,有大量免费的ThinkPHP入门教程,欢迎大家学习!
本文转自:https://blog.thinkphp.cn/825350
以上是ThinkPHP:模型三大利器之三(獲取器)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

thinkphp是国产框架。ThinkPHP是一个快速、兼容而且简单的轻量级国产PHP开发框架,是为了简化企业级应用开发和敏捷WEB应用开发而诞生的。ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,也注重易用性。

本篇文章给大家带来了关于thinkphp的相关知识,其中主要介绍了关于使用think-queue来实现普通队列和延迟队列的相关内容,think-queue是thinkphp官方提供的一个消息队列服务,下面一起来看一下,希望对大家有帮助。

thinkphp基于的mvc分别是指:1、m是model的缩写,表示模型,用于数据处理;2、v是view的缩写,表示视图,由View类和模板文件组成;3、c是controller的缩写,表示控制器,用于逻辑处理。mvc设计模式是一种编程思想,是一种将应用程序的逻辑层和表现层进行分离的方法。

thinkphp查询库是否存在的方法:1、打开相应的tp文件;2、通过“ $isTable=db()->query('SHOW TABLES LIKE '."'".$data['table_name']."'");if($isTable){...}else{...}”方式验证表是否存在即可。

本篇文章给大家带来了关于thinkphp的相关知识,其中主要介绍了使用jwt认证的问题,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于ThinkPHP的相关知识,其中主要整理了使用think-queue实现redis消息队列的相关问题,下面一起来看一下,希望对大家有帮助。

thinkphp扩展有:1、think-migration,是一种数据库迁移工具;2、think-orm,是一种ORM类库扩展;3、think-oracle,是一种Oracle驱动扩展;4、think-mongo,一种MongoDb扩展;5、think-soar,一种SQL语句优化扩展;6、porter,一种数据库管理工具;7、tp-jwt-auth,一个jwt身份验证扩展包。

thinkphp设置伪静态去除目录的方法:1、在httpd.conf配置文件中加载mod_rewrite.so模块;2、将httpd.conf中Allowoverride None的None改为All;3、修改对应的项目配置文件;4、在项目的根目录下面建立一个.htaccess文件即可。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

Atom編輯器mac版下載
最受歡迎的的開源編輯器

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

Dreamweaver Mac版
視覺化網頁開發工具