Laravel Collection型の配列変換 toArray と all の違い


LaravelのCollection型を配列に変換する方法は toArrayall の2つの方法があります。
どういった違いがあるのかどちらを使えばいいのかについて調べてみました。

環境

  • PHP 7.4.5
  • Laravel 7.9.2

tinkerで動作確認

$ php artisan tinker

>>> App\User::get()
=> Illuminate\Database\Eloquent\Collection {#3199
     all: [
       App\User {#3200
         id: 1,
         name: "Reese Kozey",
         screen_name: null,
         email: "[email protected]",
         email_verified_at: "2020-05-01 16:25:47",
         api_token: null,
         created_at: "2020-05-01 16:25:47.0",
         updated_at: "2020-05-01 16:25:47.0",
         deleted_at: null,
       },
     ],
   }

App\User::get() を実行すると Illuminate\Database\Eloquent\Collection 型が返って来ていることがわかります。

toArray で配列に変換してみましょう。

>>> App\User::get()->toArray()
=> [
     [
       "id" => 1,
       "name" => "Reese Kozey",
       "screen_name" => null,
       "email" => "[email protected]",
       "email_verified_at" => "2020-05-01T16:25:47.000000Z",
       "api_token" => null,
       "created_at" => "2020-05-01T16:25:47.000000Z",
       "updated_at" => "2020-05-01T16:25:47.000000Z",
       "deleted_at" => null,
     ],
   ]

続いて all メソッドで配列に変換します。

>>> App\User::get()->all()
=> [
     App\User {#3217
       id: 1,
       name: "Reese Kozey",
       screen_name: null,
       email: "[email protected]",
       email_verified_at: "2020-05-01 16:25:47",
       api_token: null,
       created_at: "2020-05-01 16:25:47.0",
       updated_at: "2020-05-01 16:25:47.0",
       deleted_at: null,
     },
   ]

おや?🤔 結果が異なってますね...
all の方は2次配列が App\User モデルのままです。
toArray の方は App\User も配列に変換しています。

実装

Laravelフレームワークの実際のソースコードはどのように実装されているのか見ていきましょう。

toArray

src/Illuminate/Support/Traits/EnumeratesValues.php
    /**
     * Get the collection of items as a plain array.
     *
     * @return array
     */
    public function toArray()
    {
        return $this->map(function ($value) {
            return $value instanceof Arrayable ? $value->toArray() : $value;
        })->all();
    }

Arrayable インターフェースを実装したオブジェクトのインスタンスがあれば再帰的に toArray を実行していき通常の配列に変換します。

all

src/Illuminate/Support/Collection.php
    /**
     * The items contained in the collection.
     *
     * @var array
     */
    protected $items = [];

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

all メソッドは実装がとてもシンプルですね✨
$items プロパティをそのまま返してます。

結論

実行コストが少ない all メソッドを使用するべきです。
再起的に配列に変換する必要がある場合は toArray メソッドを必要に応じて使用しましょう。

現場からは以上です。