背景
例えば、以下のコードを書くと
$user = User::get();
$thirtyUsers = $user->where('age', '30');
dd($userAttribute);
当たり前ですが、以下の結果が取得できる
Illuminate\Database\Eloquent\Collection {#2035 ▼
#items: array:3 [▶]
}
これを見て、当初は
「Illuminate\Database\Eloquent\Collectionにもwhereメソッドあるんだ~」
とのんきに思っていた。
そんなある日、同期から
「Collectionからwhereってなんで呼べるんだろ?」
という疑問を聞いたので
「Illuminate\Database\Eloquent\Collection継承してるっしょ」
と回答したところ、
「そこにはないぞ」
と一蹴された。。。
「まさか~」
と思い、見に行くとやっぱりfunction where()
の記述はない。
ごめん。同期。
「じゃあどこだ?」
と気になったので、ジャンプし続けて見つけたので、メモ。
内容
ファイルを読み込んでいく
- 前述の通り開発する上で一番よく見るCollectionである
Illuminate\Database\Eloquent\Collection
から始まる - 正式のパスは以下なので、確認
- 上述の通り、ここで
function where(
を検索しても見つからない
- 上述の通り、ここで
vendor\laravel\framework\src\Illuminate\Database\Eloquent\Collection.php
<?php
namespace Illuminate\Database\Eloquent;
...
use Illuminate\Support\Collection as BaseCollection;
...
class Collection extends BaseCollection implements QueueableCollection
{
...
}
- ここで、冒頭のクラス定義時に
BaseCollection
を継承しているらしい-
BaseCollection
とはIlluminate\Support\Collection
であるとのこと - 「ここにあるのか!」と高鳴る鼓動を落ち着かせつつ、ジャンプ
- 実際にジャンプする先は以下でした
vendor\laravel\framework\src\Illuminate\Collections\Collection.php
- 理由はnamespaceが
Illuminate\Support;
となっていたため
-
vendor\laravel\framework\src\Illuminate\Collections\Collection.php
<?php
namespace Illuminate\Support;
...
use Illuminate\Support\Traits\EnumeratesValues;
...
class Collection implements ArrayAccess, Enumerable
{
use EnumeratesValues, Macroable;
...
}
- しかし、ここでも
function where(
を検索しても見つからない- 継承はこれ以上ないので、ここで怪しそうなのは
EnumeratesValues
とMacroable
というトレイト -
Macroable
は関係なかったファイルを確認 - そして
EnumeratesValues
へジャンプ
- 継承はこれ以上ないので、ここで怪しそうなのは
結論
ここにありました。
vendor\laravel\framework\src\Illuminate\Collections\Traits\EnumeratesValues.php
/**
* Filter items by the given key value pair.
*
* @param string $key
* @param mixed $operator
* @param mixed $value
* @return static
*/
public function where($key, $operator = null, $value = null)
{
return $this->filter($this->operatorForWhere(...func_get_args()));
}
補足
vendor\laravel\framework\src\Illuminate\Collections\Traits\EnumeratesValues.php
- ここには、よくお世話になるコレクション操作用のメソッドがここにありました。
- 公式でも紹介されている便利なやつです。
- 同時に「だから、ここら辺のコレクションメソッド全部使えるのか~」と納得
- ドキュメントには今回の検証結果の途中まで記述されてました
Illuminate\Database\Eloquent\Collection
インスタンスを返します。ただし、modelKeys
などの一部のメソッドは、Illuminate\Support\Collection
インスタンスを返します。
- ただ、
EnumeratesValues
にある旨の説明は見当たらんかったですね。
所見
- 興味深かったのは、ドキュメントにないメソッドである
__toString
,getCachingIterator
,reduceWithKeys
, とかが見つかった点です。- なかなか使用ケースがマイナーかもですが、、、
- コレ知ったことにより、実務的に直接生きるかはまだわからないです。
- ですが、どこのメソッドを呼び出しているか意識して使うか否かで想定外のエラーに対応できるでしょう!(多分)
- やっぱり、コードを深く読み込んで理解するのって実務やってる中だと、なおざりにしがちなのでいい機会でした~