モデルでクエリビルダ?
モデルのクラスって、テーブルのレコードをオブジェクトにしたようなイメージでした。
でも、以下のようなコードを見ることがあると思います。
User::select('id')->first();
あれ?selectってクエリビルダだよな・・・
このUserってなんだ?クエリビルダ?モデルのクラス???
元コードを読んで見る
Modelクラス
/**
* Handle dynamic method calls into the model.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
if (in_array($method, ['increment', 'decrement'])) {
return call_user_func_array([$this, $method], $parameters);
}
$query = $this->newQuery();
return call_user_func_array([$query, $method], $parameters);
}
/**
* Handle dynamic static method calls into the method.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public static function __callStatic($method, $parameters)
{
$instance = new static;
return call_user_func_array([$instance, $method], $parameters);
}
なにしてるの?
__callStatic
__callStatic
はマジックメソッド。
静的呼び出しをされたときに使われます。
User::select('id')
このとき、 new static
でモデルのインスタンスを作成。そして call_user_func_array
で モデルクラスのインスタンスが、 select
の関数を 'id'
のパラメーターを引き継いで実行。
__call
__callStatic()
によって、静的呼び出しだったものが、モデルクラスのインスタンスから呼び出されることになります。
次は、 __call
です。静的呼び出しじゃなくなったので。
そこでは、メソッド名が ['increment', 'decrement']のどちらかか確認して、合っていれば、そのモデルクラスのメソッドを呼び出します。
なければここ! newQuery
でクエリビルダ用にインスタンスを作って、そのインスタンスで select
の関数を呼び出します!
Laravelの元コードを読むのは面白いよ!
ってことで、案外簡単に追うことができました。
Laravelの元コードは、こんな書き方あるのか!と勉強になることがたくさんあるので、是非読んでみてください!
このデザインパターン使ってるのか・・・!ってなることたくさんあります。おすすめです。
参考
PHP: in_array - Manual
PHP: call_user_func_array - Manual