2

In a classic foreach() loop after the word as, is it possible to use the key variable as part of the value variable or vice versa?

* after more than a decade of PHP development, this possibility only just now occurred to me to investigate.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136

1 Answers1

2

A foreach() always assigns the value variable before assigning the key variable. (Demo)

This seems a little counterintuitive because $v visually appears to be declared after it is access by key declaration.

This means you can safely use:

$array = ['a', 'b'];
$result = [];
foreach ($array as $result["prefix_$v"] => $v);
var_export($result);

to produce:

array (
  'prefix_a' => 0,
  'prefix_b' => 1,
)

The newly generated array has prefixed keys based on the original values and the original indexes become the new values.

Without the prefix_ prepended to the string, the action is effectively the same as array_flip().


Reversing the assignments so that the value variable receives the key does not work as intended. You might hope to generate ["prefix_0", "prefix_1"] but it does not and it also generates Notices/Warnings due to trying to access an undeclared variable. (The complaint is only on the first iteration because after the first iteration, $k is declared -- it is the previous iteration's key.)

$array = ['a', 'b'];
$result = [];
foreach ($array as $k => $result["prefix_$k"]);
// not defined on first iteration -------^^
var_export($result);

Bad Output:

Warning: Undefined variable $k in /in/iVm1u on line 6
array (
  'prefix_' => 'a',
  'prefix_0' => 'b',
)

For additional context, I'll offer one more working example that generates a multi-dimensional array using the value to determine the array keys in the output array. (Demo)

$array = [2, 3, 5];

$result = [];
foreach ($array as $result[$v * $v][$v] => $v);
var_export($result);

Output:

array (
  4 => 
  array (
    2 => 0,
  ),
  9 => 
  array (
    3 => 1,
  ),
  25 => 
  array (
    5 => 2,
  ),
)
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
  • May be of note, that this also works with `list()` - https://3v4l.org/JCSIi – Hendrik Feb 08 '22 at 08:43
  • 1
    Yes, originality I had a more complex example using array destructuring like that, but in the end I decided to try to produce the simplest possible demonstration to reduce confusion. That technique is kind of like a fusion of `array_flip()` and `array_column()`. – mickmackusa Feb 08 '22 at 08:48