57

Example:

list($fruit1, $fruit2) = array('apples', 'oranges');

code above of course works ok, but code below:

list($fruit1, $fruit2) = array('fruit1' => 'apples', 'fruit2' => 'oranges');

gives: Notice: Undefined offset: 1 in....

Is there any way to refer to named keys somehow with list like list('fruit1' : $fruit1), have you seen anything like this planned for future release?

ashleedawg
  • 20,365
  • 9
  • 72
  • 105
rsk82
  • 28,217
  • 50
  • 150
  • 240
  • Food for thought: [While destructuring an array, can the same element value be accessed more than once?](https://stackoverflow.com/q/71807960/2943403) ...and you can choose to omit elements during destructuring too. – mickmackusa May 13 '22 at 15:05

7 Answers7

105

With/from PHP 7.1:

For keyed arrays;

$array = ['fruit1' => 'apple', 'fruit2' => 'orange'];

// [] style
['fruit1' => $fruit1, 'fruit2' => $fruit2] = $array;

// list() style
list('fruit1' => $fruit1, 'fruit2' => $fruit2) = $array;

echo $fruit1; // apple

For unkeyed arrays;

$array = ['apple', 'orange'];

// [] style
[$fruit1, $fruit2] = $array;

// list() style
list($fruit1, $fruit2) = $array;

echo $fruit1; // apple

Note: use [] style if possible by version, maybe list goes a new type in the future, who knows...

Kerem
  • 11,377
  • 5
  • 59
  • 58
51

EDIT: This approach was useful back in the day (it was asked & answered nine years ago), but see Kerem's answer below for a better approach with newer PHP 7+ syntax.

Try the extract() function. It will create variables of all your keys, assigned to their associated values:

extract(array('fruit1' => 'apples', 'fruit2' => 'oranges'));
var_dump($fruit1);
var_dump($fruit2);
Kerem
  • 11,377
  • 5
  • 59
  • 58
landons
  • 9,502
  • 3
  • 33
  • 46
  • 1
    Yes, this works. On the other hand, it is almost always good practice to supply a prefix when using `extract` unless you are 100% absolutely certain which keys will be present. – lonesomeday Dec 04 '11 at 22:25
  • 1
    Yes, I'd run it with array_intersect_key() first with expected keys. – landons Dec 04 '11 at 22:29
  • But this won't work if you have an array like you get from `getimagesize()`. – Jurik May 07 '14 at 09:01
  • @Jurik, true. Using `list()` would be the way to go on `getimagesize()` – landons May 07 '14 at 20:07
  • No, `list()` won't work either. Because the last two elements of this array have non numerical keys. I do not get it why they did such non sense with `getimagesize()`. – Jurik May 08 '14 at 08:06
  • 3
    @Jurik, have you tried using `list()` with `array_values()`? You're right though--that function is weird. – landons May 13 '14 at 14:56
  • Yeah, that is my [solution](http://stackoverflow.com/questions/23562608/how-to-convert-getimagesize-result-to-variables) too. – Jurik May 14 '14 at 08:07
  • 15
    Please don't use `extract`. IDEs can't handle it. And it can create a [host of other problems.](http://stackoverflow.com/a/829454/178910) – peter Oct 08 '15 at 19:05
  • my suggestion is to set variables in comment, so IDEs can read it, like `extract(array('fruit1'=>'apples','fruit2'=>'oranges')); /** * @var Array $fruit1 * @var Array $fruit2 */` – Full May 09 '16 at 12:27
  • A very unreadable and bad solution! `list()` is much as readable as `extract` is. – Saeed Falsafin Jan 01 '18 at 07:25
  • see @K-Gun's answer for a PHP 7.1 solution. as peter mentioned, extract() is an old function that comes with a lot of problems, both subtle and catastrophic. the PHP doc page on extract() itself comes with a couple different warnings about its use: http://php.net/manual/en/function.extract.php – Ben Oct 22 '18 at 14:28
  • I agree with peter, the only way for my IDE to know that the variables exist (and not mark them in red) is be declaring a /** @var $variableName **/ in front of the extract – user1015214 Oct 29 '18 at 13:47
  • PHP 7.1 offers a cleaner way - see K-Gun's answer instead. – Bananaapple Dec 05 '18 at 09:20
  • 1
    @Bananaapple, I've edited my answer accordingly. I may be biased, but I'm not sure downvoting answers that were true at the time is necessarily the right approach. Thanks for calling it to my attention though. – landons Jan 02 '19 at 22:46
  • I definitely see were you are coming from @landons but on the other hand it did have the desired effect - maybe something to enquire about on meta. In any case, thanks for the edit! – Bananaapple Jan 03 '19 at 08:32
  • hmm... what if your array is like `array('omer@email.com'=>'Omer Aslam','landons@email.com'=>'Landons')` how are you going to access them ? – Muhammad Omer Aslam Jan 03 '21 at 23:49
50

What about using array_values()?

<?php
   list($fruit1, $fruit2) = array_values( array('fruit1'=>'apples','fruit2'=>'oranges') );
?>
Broom
  • 533
  • 4
  • 2
0

It's pretty straightforward to implement.

function orderedValuesArray(array &$associativeArray, array $keys, $missingKeyDefault = null)
{
    $result = [];
    foreach ($keys as &$key) {
        if (!array_key_exists($key, $associativeArray)) {
            $result[] = $missingKeyDefault;
        } else {
            $result[] = $associativeArray[$key];
        }
    }
    return $result;
}
$arr = [
    'a' => 1,
    'b' => 2,
    'c' => 3
];
list($a, $b, $c) = orderedValuesArray($arr, ['a','AAA', 'c', 'b']);
echo $a, ', ', $b, ', ', $c, PHP_EOL;

output: 1, , 3

  • less typing on usage side
  • no elements order dependency (unlike array_values)
  • direct control over variables names (unlike extract) - smaller name collision risk, better IDE support
Alexander Malakhov
  • 3,383
  • 2
  • 33
  • 58
  • I see no benefit to making `$key` modifiable in the `foreach()` -- you never attempt to modify it. – mickmackusa May 13 '22 at 15:00
  • @mickmackusa, I haven't programmed in PHP since 2017, but I think I did that to ensure `$key` isn't copied. Can't tell for sure at this point if that was my intention, or if that actually makes any technical difference. – Alexander Malakhov May 13 '22 at 16:51
0

If you are in my case:

list() only works on numerical array. So if you can, leaving blank in fetch() or fetchAll() -> let it have 2 options: numerical array and associative array. It will work.

-3

consider this an elegant solution:

<?php

    $fruits = array('fruit1'=> 'apples','fruit2'=>'oranges');  

    foreach ($fruits as $key => $value)  
    {
        $$key = $value;  
    }
    echo $fruit1; //=apples  

?>
Walfie
  • 3,376
  • 4
  • 32
  • 38
krommer_b
  • 11
  • 1
-5
<?php

function array_list($array)
{
    foreach($array as $key => $value)
    $GLOBALS[$key] = $value;
}

$array = array('fruit2'=>'apples','fruit1'=>'oranges');

array_list($array);

echo $fruit1; // oranges


?>
Dejan Marjanović
  • 19,244
  • 7
  • 52
  • 66