Join 26,000+ Laravel Developers and join the free Laravel Newsletter
Unwrapping array_wrap()
News / updated: November 29, 2018

Unwrapping array_wrap()

Laravel has a wrap method and array_wrap() helper to normalize values into an array. Raul @rcubitto shared this nice tip about it on Twitter and before seeing his Tweet I wasn’t aware of this method:

I noticed that some people asked in response to Raul’s tweet why that was needed vs. casting to an array:

$value = (array) $value;

Typecasting works for primitive values, but “iterables” get treated differently. For example, let’s say you want to allow a user to pass either one Eloquent model or an array of models. Here’s what happens when you try to cast a single model to an array with (array):

>>> $u = \App\User::create([
    'name' => 'Admin',
    'email' => 'admin@example.com',
    'password' => bcrypt('secret')
]);
>>> (array) $u
=> [
     "\0*\0fillable" => [
       "name",
       "email",
       "password",
     ],
     "\0*\0hidden" => [
       "password",
       "remember_token",
     ],
     "\0*\0connection" => "mysql",
     "\0*\0table" => "users",
     "\0*\0primaryKey" => "id",
     "\0*\0keyType" => "int",
     "incrementing" => true,
     "\0*\0with" => [],
     "\0*\0withCount" => [],
     "\0*\0perPage" => 15,
     "exists" => true,
     "wasRecentlyCreated" => true,
     "\0*\0attributes" => [
       "name" => "Admin",
       "email" => "admin@example.com",
       "password" => "$2y$10$LtI7hHc.eZQi9BcU61Qp3eTXliFrBq03Lav1QpLlDFvBNbsPYklYS",
       "updated_at" => "2018-11-28 23:14:40",
       "created_at" => "2018-11-28 23:14:40",
       "id" => 1,
     ],
     ....
   ]

Here’s how array_wrap() treats the same value:

>>> array_wrap($u)
=> [
     App\User {#2897
       name: "Admin",
       email: "admin@example.com",
       updated_at: "2018-11-28 23:14:40",
       created_at: "2018-11-28 23:14:40",
       id: 1,
     },
   ]

The helper documentation states “If the given value is not an array and not null, wrap it in one.” and looks like this at the time of writing:

/**
 * If the given value is not an array and not null, wrap it in one.
 *
 * @param  mixed  $value
 * @return array
 */
public static function wrap($value)
{
    if (is_null($value)) {
        return [];
    }

    return is_array($value) ? $value : [$value];
}

How is this helper useful?

As stated, the helper takes care of null values and returns an empty array when the value is null. Laravel has various places in the framework where you can pass an array of values or a single value. Normalizing like this makes for a nice API and Laravel takes care of creating a consistent array behind the scenes.

Here’s an example of setting the model on the ModelNotFoundException class using Arr::wrap:

/**
 * Set the affected Eloquent model and instance ids.
 *
 * @param  string  $model
 * @param  int|array  $ids
 * @return $this
 */
public function setModel($model, $ids = [])
{
    $this->model = $model;
    $this->ids = Arr::wrap($ids);

    $this->message = "No query results for model [{$model}]";

    if (count($this->ids) > 0) {
        $this->message .= ' '.implode(', ', $this->ids);
    } else {
        $this->message .= '.';
    }

    return $this;
}

The wrap method is found in the Arr class (Illuminate\Support\Arr) which has an accompanying array_wrap helper function you can use in Laravel apps.

Laravel News Partners

Newsletter

Join the weekly newsletter and never miss out on new tips, tutorials, and more.