In CoffeeScript, Clojure, ES6 and many other languages we have destructuring of objects/maps/etc somewhat like this:
obj = {keyA: 'Hello from A', keyB: 'Hello from B'} {keyA, keyB} = obj
I've found the list
function in php which lets you destructure arrays like so:
$info = array('coffee', 'brown', 'caffeine'); list($drink, $color, $power) = $info;
Is there a way to destructure objects or associative arrays in PHP? If not in the core libs maybe someone wrote some smart helper function?
Destructuring in Objects When destructuring objects, we use curly braces with the exact name of what we have in the object. Unlike in arrays where we can use any variable name to unpack the element, objects allow just the use of the name of the stored data.
This language construct is used to "pull" variables out of an array. In other words: it will "destructure" the array into separate variables.
In the first line, we are declaring a new variable studentsArr , and assigning it the value of an array of student names. Line 2 is where we destructure. In line 2 we declare three variables; first , second , and third . By declaring them on the left-hand side, we initiate destructuring.
Object Destructuring (PHP 7.1) Unfortunately there is no object destructuring. However you can convert an object to an associative array using get_object_vars , and then use associative array destructuring.
For PHP 7.0 and below that is beyond the functionality of list
. The docs state:
list only works on numerical arrays and assumes the numerical indices start at 0.
One of the things that could suit your purpose would be the extract()
function which imports variables from an array into the current symbol table. While with list
you are able to define variable names explicitly, extract()
does not give you this freedom.
Extracting an associative array
With extract
you could do something like that:
<?php $info = [ 'drink' => 'coffee', 'color' => 'brown', 'power' => 'caffeine' ]; extract($info); var_dump($drink); // string(6) "coffee" var_dump($color); // string(5) "brown" var_dump($power); // string(8) "caffeine"
Extracting an Object
Extracting an object works almost the same. Since extract
only takes an array as an argument we need to get the objects properties as an array. get_object_vars
does that for you. It returns an associative array with all public properties as key and their values as value.
<?php class User { public $name = 'Thomas'; } $user = new User(); extract( get_object_vars($user) ); var_dump($name); // string(6) "Thomas"
Pitfalls
extract()
is not the same as list
since it does not allow you to explicitly define the variable names that get exported to the symbol table. The variable names correspond the array keys by default.
list
is a language construct while extract()
is a functionWith the $flags
parameter that you can pass as second argument to extract()
you can influence the behavior in case of colliding or invalid variables. But still it's important to know how extract()
works and to use it with cauton.
http://php.net/manual/en/migration71.new-features.php#migration71.new-features.support-for-keys-in-list
You can now specify keys in list(), or its new shorthand [] syntax. This enables destructuring of arrays with non-integer or non-sequential keys.
https://php.net/manual/en/migration71.new-features.php#migration71.new-features.symmetric-array-destructuring
The shorthand array syntax ([]) may now be used to destructure arrays for assignments (including within foreach), as an alternative to the existing list() syntax, which is still supported.
For example this:
$test_arr = ['a' => 1, 'b' => 2]; list('a' => $a, 'b' => $b) = $test_arr; var_dump($a); var_dump($b);
Will output the following as of 7.1.0
int(1) int(2)
I noticed the accepted answer missed out examples that use the short-hand notation, security issues with using extract, and IDE issues.
As of PHP 7.1 numerical array destructuring (Symetric array destructuring) is supported like so:
<?php $data = [55, 'John', 'UK']; [$id, $name] = $data; // short-hand (recommended) list($id, $name) = $data; // long-hand
Notice that you can miss items out if you don't want them.
You can also destructure associative arrays (Support for keys in list) like so:
<?php $data = ['id' => 55, 'firstName' => 'John', 'country' => 'UK'] ['id' => $id, 'firstName' => $name] = $data; // short-hand (recommended) list('id' => $id, 'firstName' => $name) = $data; // long-hand
Notice that you can miss items out if you don't want them. Also the variable name can be different to the property name.
Unfortunately there is no object destructuring. However you can convert an object to an associative array using get_object_vars
, and then use associative array destructuring.
<?php class User { public $id; public $name; public $country; } $user = new User(); $user->id = 55; $user->name = 'John'; $user->country = 'UK'; ['id' => $id, 'firstName' => $name] = get_object_vars($user)
However, this can break some IDE features. These are some issues I noticed when using PHPStorm 2019.1:
@var Type
PHPDocs to maintain auto-complete functionalitySo I recommend just doing it the normal way:
$id = $user->id $name = $user->firstName
extract
With extract, all variables are always set. There it is a really bad idea to use it because:
$_GET
, $_POST
), unless you want to make a malicious hacker's day.EXTR_SKIP
flag or similarIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With