ゲッターの定義
ゲッターの機能は、モデルの (元の) データを自動的に処理することです。物体 。ゲッターはモデルの特別なメソッドに対応します (メソッドはパブリック タイプである必要があります)。メソッドの命名規則は次のとおりです:
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 という名前のゲッターを定義する場合、次のようになります。も許可されていますが、この時点で最初のパラメーターがゲッターに渡されることに注意する必要があります。パラメーターには値がなくてはならず (対応するデータ テーブル フィールド データがないため)、必要なデータは 2 番目のパラメーターを通じてのみ取得できます。 。
<?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'] が存在するかどうかを判断する必要もありますが、ここではスキップします。
2 番目のパラメーターのデータ data 自体がゲッターによって処理されている可能性があることに注意してください (関連するゲッターを定義している場合)。
なぜデータグラム フィールドと矛盾するゲッターを定義する必要があるのでしょうか?最も明白な利点は、さまざまなフィールドを区別して生データと処理済みデータを取得できることです。実際、データ テーブルに存在しないフィールド ゲッターを定義する理由は数多くありますが、これがまさにゲッターの魅力です。
ゲッターの定義自体は難しくないことがわかりますが、鍵となるのはメソッド内の取得ロジックであり、実際のアプリケーションで最も注意すべき点です。
ゲッターを呼び出す
ゲッターを定義すると、次の状況でゲッターが自動的にトリガーされます:
·モデルのデータ オブジェクト値操作 ($model->field_name など);
·モデルのシリアル化された出力操作($model->toArray() や toJson() など);
##getAttr メソッドを明示的に呼び出します (例: $model->getAttr( 'field_name'));
最初の 2 つは、最後のものを呼び出すことによって実際に実装されます。最も重要なことは、最初のものを理解することです。モデル オブジェクトの値を取得する場合、一般的に次のメソッドを使用します。$user = User::get(1); echo $user->name; echo $user->user_type;
#ステップ 1 - クエリ結果にフィールド データが含まれている場合は、元のデータを取得します。それ以外の場合は、ステップ 2 に進みます。
·ステップ 2 - このフィールドのゲッター (動的ゲッターを含む) が定義されているかどうかを確認します。定義されている場合は、ゲッターを呼び出して結果を返します。そうでない場合は、ステップ 3 に進みます。
·ステップ 3 - フィールド型変換が定義されているかどうかを確認し、定義されている場合は変換処理を実行して結果を返します。定義されていない場合はステップ 4 に進みます。
·ステップ 4 - システム時刻フィールドの場合、時刻は自動的にフォーマットされて結果が返されます。それ以外の場合は、ステップ 5 に進みます。
##ステップ 5 - チェックの最初のステップにフィールド データが含まれていない場合は、関連付けられた属性定義があるかどうかを確認し、関連付けられている場合はデータを取得します。関連付けられたリレーションシップを介して結果を返します。それ以外の場合は、プロパティの未定義例外がスローされます。 上記の 5 つのステップの詳細なコードについては、興味があれば、think\model\concern\Attribute の getAttr メソッド コードを直接参照できます。
ただし、多くの場合、モデル データを 1 つずつ取得するのではなく、モデル データ全体をクライアントまたはテンプレートに返します。簡単に言えば、$user->user_type を取得すると、user_type フィールドが実際のデータ テーブル フィールドであるかどうかに関係なく、関連するゲッターが定義されているかどうかを確認します。
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'])); }
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: モデル用の 3 つの強力なツール (ゲッター) のうちの 3 番目の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。