LoginSignup
2
2

More than 1 year has passed since last update.

[Laravel]<Collection>→where()ってなんで書けるか分かる?

Posted at

背景

例えば、以下のコードを書くと

$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(を検索しても見つからない
    • 継承はこれ以上ないので、ここで怪しそうなのはEnumeratesValuesMacroableというトレイト
    • 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, とかが見つかった点です。
    • なかなか使用ケースがマイナーかもですが、、、
  • コレ知ったことにより、実務的に直接生きるかはまだわからないです。
  • ですが、どこのメソッドを呼び出しているか意識して使うか否かで想定外のエラーに対応できるでしょう!(多分)
  • やっぱり、コードを深く読み込んで理解するのって実務やってる中だと、なおざりにしがちなのでいい機会でした~
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2