Collection::toArray

Converts the collection to a plain array, turning any Arrayable items into arrays too.

Signature
public function toArray(): array

Return value

array<TKey, mixed>A plain PHP array with the collection's keys intact, in which every item implementing Illuminate\Contracts\Support\Arrayable has been replaced by its own toArray() result.

toArray maps over the items, replacing anything that implements Illuminate\Contracts\Support\Arrayable with its own toArray() output, and returns the plain array. Keys are preserved exactly.

toArray versus all

all() hands back the raw backing array untouched, objects and all. toArray() converts. That single difference decides which one you want: all() when you still need the objects (you are about to call methods on them), toArray() when the result is leaving PHP — a view, a queue payload, a JSON response, an assertion.

What trips people up

The conversion applies to the collection's own items. Deeper nesting only flattens because those objects' toArray() methods recurse — a nested Collection or Eloquent model does, an arbitrary value object may not. If a plain object survives inside the result, it is because nothing in the chain converted it.

Arrayable is the only interface honoured here. An object implementing just JsonSerializable passes through unchanged, even though toJson() would serialize it — so toArray() and json_decode($c->toJson(), true) are not always the same shape. On Eloquent models, toArray() also applies hidden/visible rules and casts, so it is not a raw attribute dump.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Turn a collection of models into arrays for a queued job payload
  • Flatten nested collections before passing data to a view or template
  • Compare a collection against an expected array in a test assertion
  • Hand structured data to a function that type-hints array, not iterable

Frequently asked questions

What is the difference between toArray() and all() on a Laravel collection?

all() returns the raw backing array with objects untouched, while toArray() replaces every item implementing Arrayable with its array form. Use all() when you still need the objects and toArray() when the data is leaving PHP.

Does toArray() convert nested objects recursively?

Only through the objects themselves. toArray() converts the collection's own Arrayable items, and nesting flattens further only because those objects' toArray() methods recurse, as Collection and Eloquent models do.

Why is toArray() giving a different shape than my JSON response?

toArray() honours only the Arrayable interface, while toJson() goes through jsonSerialize() and also handles JsonSerializable and Jsonable. An object implementing only JsonSerializable survives toArray() but is expanded in the JSON.

More examples

Nested collections flatten all the way down

Collection itself implements Arrayable, so the inner collection is converted, and its own toArray() converts the collections inside it. The recursion is not something toArray() does on its own — it is each nested Arrayable calling toArray() in turn.

Example · php
<?php

$order = collect([
    'reference' => 'ORD-4021',
    'lines'     => collect([
        collect(['sku' => 'DESK-1', 'qty' => 2]),
        collect(['sku' => 'LAMP-3', 'qty' => 1]),
    ]),
]);

print_r($order->toArray());

// Output:
// Array
// (
//     [reference] => ORD-4021
//     [lines] => Array
//         (
//             [0] => Array ( [sku] => DESK-1 [qty] => 2 )
//             [1] => Array ( [sku] => LAMP-3 [qty] => 1 )
//         )
//
// )

JsonSerializable is not converted

toArray() checks only for Arrayable, so the Temperature object passes straight through. toJson() goes via jsonSerialize(), which does honour JsonSerializable. If you need the array form of such an object, implement Arrayable as well.

Example · php
<?php

class Temperature implements JsonSerializable
{
    public function __construct(public float $celsius) {}

    public function jsonSerialize(): mixed
    {
        return ['c' => $this->celsius];
    }
}

$readings = collect(['outside' => new Temperature(4.5)]);

// The object survives toArray() untouched...
var_dump($readings->toArray()['outside'] instanceof Temperature);

// ...but toJson() serializes it.
echo $readings->toJson(), "\n";

// Output:
// bool(true)
// {"outside":{"c":4.5}}

Models in an application context

On Eloquent collections toArray() is not a raw column dump: $hidden is stripped, accessors listed in $appends are added and casts are resolved, which is exactly what you want for a queue payload or an API response. all() bypasses all of that and returns the model objects themselves. Needs a booted application with a database.

Example · php
<?php

use App\Models\User;

$users = User::with('roles')->take(2)->get();

// Each model becomes an array; the loaded relation becomes a nested array.
$payload = $users->toArray();

// Hidden attributes (password, remember_token) are excluded,
// and casts have already been applied.
dump($payload[0]['email'], array_key_exists('password', $payload[0]));

// Keep the models instead when you still need their methods:
$models = $users->all();
dump($models[0]->fullName());

Discussion

  • Be the first to comment on this lesson.