Unwrapping array_wrap()

Tutorials

November 29th, 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:

Did you know about the array\_wrap function? Nice little wrapper for a snippet we've all written at least once in our lives #Laravel pic.twitter.com/Pg3zFJhxzO

— Raul (@rcubitto) June 22, 2017

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.

Filed in:

Paul Redmond

Full stack web developer. Author of Lumen Programming Guide and Docker for PHP Developers.