Reputation: 35
I want to implement a function
$input = ['key1', 'value1', 'key2', 'value2'];
// $output = ['key1' => 'value1', 'key2' => 'value2'];
$output=[];
do {
$output[current($input)] = next($input);
} while (next($input));
I wrote this code intuitively, but when I reviewed this code today, I pondered if this might be a bug.
I assumed the output should be something like this:
['value1'=>'value1','value2'=>'value2']
because next()
takes precedence over current()
, but this function works fine in PHP8.
Why is this? Isn't assignment from right to left?
Upvotes: -2
Views: 105
Reputation: 4751
Operator precedence and associativity, and order of evaluation are different things.
The first two tell you how to interpret an expression, i.e. x() - y() - z()
means (x() - y()) - z()
,
but they don't tell you in which order each operand will be evaluated.
The PHP documentation on Operator Precedence says (emphasis added):
Operator precedence and associativity only determine how expressions are grouped, they do not specify an order of evaluation. PHP does not (in the general case) specify in which order an expression is evaluated and code that assumes a specific order of evaluation should be avoided, because the behavior can change between versions of PHP or depending on the surrounding code.
I ran a couple of tests on PHP 8.3.10 and in this case the functions are evaluate Left-to-Right regardless of associativity.
<?php
function f1 () { echo "f1"; return 1; }
function f2 () { echo "f2"; return 1; }
$v = f1() + f2(); /* Left-to-Right */
echo "\n"; /* Output: f1f2 */
<?php
function f1 () { echo "f1"; return 1; }
function f2 () { echo "f2"; return 1; }
$v = f1() ** f2(); /* Right-to-Left */
echo "\n"; /* Output: f1f2 */
See also a Example 2 in the PHP documentation:
$i = 1; $array[$i] = $i++; // may set either index 1 or 2
Upvotes: 0
Reputation: 17825
The associativity is from left to right for =
for your case. You can cross check this with the below snippet where t1
gets printed first instead of t2
.
<?php
$output=[];
$output[test('t1')] = test('t2');
function test($str){
echo $str,PHP_EOL;
return rand(10, 100);
}
Hence, your output is [ 'key1' => 'value1','key2' => 'value2']
because current()
gives key1
and next()
advances the internal array pointer and returns the element value which is value1
and the same gets repeated over until the array is looped completely.
Upvotes: 2