Define the getter
The function of the getter is to automatically process the (original) data of the model object . A getter corresponds to a special method of the model (the method must be of public type). The method naming convention is:
getFieldNameAttr
FieldName is the camel case conversion of the data table field Or a field that does not exist in your data table (pay attention to understanding the following sentence). The following is a typical getter definition:
<?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]; } }
You need to define a corresponding getter for each data field that requires output conversion processing. But the field name of the getter does not have to be consistent with the field name of the data table. For example, if I want to define a getter named getTypeAttr for the user_type field, it is also allowed, but it should be noted that the first one passed into the getter at this time The parameter must have no value (because there is no corresponding data table field data), and you can only get the data you need through the second parameter.
<?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']]; } }
Of course, in a more rigorous case, you also need to determine whether $data['user_type'] exists, which will be skipped for now.
Note that the data data of the second parameter may itself have been processed by the getter (if you define the relevant getter).
Why do we need to define a getter that is inconsistent with the datagram field? The most obvious benefit is the ability to differentiate between different fields to obtain raw data and processed data. In fact, there are many reasons for you to define some field getters that do not exist in the data table. This is precisely the charm of getters.
It can be seen that the definition of the getter itself is not difficult. The key lies in the acquisition logic in the method, which is the most important thing to pay attention to in practical applications.
Call the getter
After defining the getter, it will be automatically triggered in the following situations:
·The data object value operation of the model (such as $model->field_name);
·The serialized output operation of the model (such as $model-> toArray() or toJson());
##·Explicitly call the getAttr method (for example $model->getAttr('field_name'));
The first two are actually implemented by calling the last one. The most important thing is to understand the first one. When we obtain the value of a model object, we generally use the following method:$user = User::get(1); echo $user->name; echo $user->user_type;
·Step 1 - If the query result contains the field data, retrieve the original data, otherwise go to step 2;
·Step 2 - Check whether the getter (including dynamic getter) of this field is defined. If so, call the getter to return the result. If not, go to step 3;
·Step 3 - Check whether the field type conversion is defined, if so, perform conversion processing and return the result, if not, proceed to step 4;
·Step 4 - If it is a system time field, the time will be formatted automatically and the result will be returned, otherwise go to step 5;
·Step 5 - If the field data is not included in the first step of the check, check whether there is an associated attribute definition, and if so, obtain the data through the associated relationship and Returns the result, otherwise throws a property undefined exception.
For the detailed code of the above five steps, if you are interested, you can directly refer to the getAttr method code of think\model\concern\Attribute.To put it simply, when you get $user->user_type, you will check whether the relevant getter is defined, regardless of whether the user_type field is a real data table field. But in many cases, you will not get the model data one by one, but return the entire model data to the client or template.
public function index() { $user = User::get(1); return json($user); }
public function index() { $user = User::get(1); return json($user->append(['type'])); }
public function index() { $users = User::all(); return json($users->append(['type'])); }
In addition to the append method, we also support using the hidden method to temporarily hide some data.
Get original data
有些情况下,除了要获取处理过的数据外,还需要获取原始数据以便应对不同的需求。
如果你的获取器都是用的区分于实际数据表字段的额外属性字段,那么这个问题本身已经解决了。所以我们主要讨论的是当你的获取器属性和数据表字段一致的情况下,该如何获取原始数据。
一个最简单的办法是使用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
The above is the detailed content of ThinkPHP: The third of three powerful tools for models (getter). For more information, please follow other related articles on the PHP Chinese website!