-3

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?

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
caijw
  • 25
  • 6
  • 3
    You haven't explained what output you're getting in whatever version of PHP you think is problematic, or what version of PHP you think has a bug. The problem with code like this is that you might think it's elegant and clever, but clearly it's purpose is not clear to PHP. Some poor soul who comes along after you may not understand it either. Always go for clarity. Always. – Tangentially Perpendicular Apr 11 '23 at 01:19
  • I tried this in [3v4l](https://3v4l.org/8h36m) It produced the same output in every PHP version back as far as 5.4. PHP5.3 failed because it didn't like the shortform array notation. I think the problem is in your head. – Tangentially Perpendicular Apr 11 '23 at 01:34
  • Sorry, there is a problem with my expression. What I mean is not which version of php will have different output, but I think that the assignment operator is operated from right to left, so it should execute next before executing current, but actually In the operation, the current is first and then the next (at least in php8), this is my doubt, why the operation logic is from right to left, but the order of execution is not like this @TangentiallyPerpendicular I've changed the logic to the following, just out of curiosity $key = current($input); $output[$key] = next($input); – caijw Apr 11 '23 at 03:50
  • Kind of, sort of on this topic: [Within a foreach() expression, is the value defined before or after the key?](https://stackoverflow.com/q/71030746/2943403) – mickmackusa Apr 11 '23 at 05:00
  • Concise alternatives: [`array_column(array_chunk($input, 2), 1, 0)`](https://3v4l.org/Z46an) and to destroy the keys: [`array_column(array_chunk($input, 2), 1, 1)`](https://3v4l.org/Kfu3V) – mickmackusa Apr 11 '23 at 20:32

1 Answers1

2

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);
}

Demo

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.

nice_dev
  • 17,053
  • 2
  • 21
  • 35
  • 1
    First of all, thank you for answering my question about who executes first, maybe I mixed up the order of assignment and the order of execution Secondly, I'm sorry, I have a problem with the description. The result I want is ['key'=>'value'], but what I mentioned in the title is just that I think the execution result of this code should be ['value'=> 'value'] @mickmackusa – caijw Apr 11 '23 at 04:59
  • @caijw Fair enough. I removed the irrelevant part. – nice_dev Apr 11 '23 at 05:02