40秒で把握するCollectionのall()

Laravel11公式ドキュメントのCollectionメソッド all()についてみていきます。段階的に見ていきますが、LaravelのCollectionについて把握していない方は、以下の記事を先に見るとこの記事が読みやすくなると思います。

LaravelのCollectionに触れる

この記事で得られること

  • all()の概要
  • all()の実装コードを見る体験

メソッドの概要を見る

Laravel – The PHP Framework For Web Artisans

公式ドキュメントを日本語訳してからの引用

この**all**メソッドは、コレクションによって表される基になる配列を返します。

collect([1, 2, 3])->all();
 
// [1, 2, 3]
  • allメソッドはコレクションのもとになる配列を返す

説明文がシンプルを極めてますね。

メソッドのソースを見る

概要は何となく掴めてきたので早速ソースを見ていきます。

vendor/laravel/framework/src/Illuminate/Collections/Collection.php(63行目あたり)

    /**
     * Get all of the items in the collection.
     *
     * @return array<TKey, TValue>
     */
    public function all()
    {
        return $this->items;
    }

ソースもシンプルを極めてますね。$thisは元のコレクションを指します。そこからitemsというプロパティを取得しているようです。

検証してみる

メソッドの実際の挙動について以下を検証してみます。

  • 元のコレクションから直接itemsを呼び出してみる

検証に使ったコード(/bootstrap/app.phpのreturnの前に適当に記述)

$result = collect([1, 2, 3]);
$items = $result->items;

// [1, 2, 3]
dd($result);

コードを実行(ターミナルに結果が出力されます。)

php artisan serve

実行結果

PHP Fatal error:  Uncaught Exception: Property [items] does not exist on this collection instance. in /{Users}/laravel11-prac/vendor/laravel/framework/src/Illuminate/Collections/Traits/EnumeratesValues.php:1034
Stack trace:
#0 /{Users}/laravel11-prac/bootstrap/app.php(9): Illuminate\\Support\\Collection->__get('items')
#1 /{Users}/artisan(12): require_once('/{Users}...')
#2 {main}
  thrown in /{Users}/vendor/laravel/framework/src/Illuminate/Collections/Traits/EnumeratesValues.php on line 1034

エラーが発生しました。内容としては、items というプロパティがコレクション・インスタンスに存在しないというもののようです。どういう事かソースを追うとitemsについての記述箇所を見つけました。

vendor/laravel/framework/src/Illuminate/Collections/Collection.php(28行目あたり)

    /**
     * The items contained in the collection.
     *
     * @var array<TKey, TValue>
     */
    protected $items = [];

どうやら protected 修飾子がついているようです。これは、アクセス修飾子というものでprotectedの場合は以下の特徴を持ちます。

  • 自分のクラス内、もしくは継承先のクラスならばアクセス可能

先の検証コードではcollect()により作ったコレクションのitemsに直接アクセスしようとしていましたが、呼び出しているのがCollectionクラスでは無いためエラーになったという事ですね。

クラスにはgetterと言ってクラスで定義したプロパティを呼び出す専用のメソッドを定義することがあります。今回のall()を見てみるとCollectionクラスで定義しているitems プロパティを$this→items のように返しているので内部の処理的にはgetterに近いと思われます。

まとめ

コレクションのall()メソッドは以下のような特徴を持つ

  • 元になるコレクションを配列で返す。
  • 実装はCollectionクラス内で定義されているitemsプロパティのgetterに近い

all()の実装は予想では、コレクションを配列にするためにもっと複雑な処理をしていると思ってましたが、公式ドキュメントの説明文がシンプルなように実装もシンプルなものでした。

おまけ CursorAI(GPT-4)に聞いたときに使った質問文

1ラウンド目

下記はLaravelのCollectionクラス内の記述です。
コードの解説を以下の点を踏まえてお願いします。
- 段階的に行う
- 小学生でも分かるような言葉を使う
- コードの引用を混じえる

"""
    /**
     * The items contained in the collection.
     *
     * @var array<TKey, TValue>
     */
    protected $items = [];
 
...

    /**
     * Get all of the items in the collection.
     *
     * @return array<TKey, TValue>
     */
    public function all()
    {
        return $this->items;
    }
 
"""

コメント

タイトルとURLをコピーしました