1

I have a function that work good in php 7 but in php 8.0.11 has warning

$orders->result = array_map('reset', $orders->result);

E_WARNING: reset(): Argument #1 ($array) must be passed by reference, value given in

Of course, I can use this code instead that but maybe slower than array_map

foreach ($orders->result as $item)
       $result[$item[0]['order_id']] = $item[0];

Edit: before foreach or array_map the output like this

    Array
(
    [0] => Array
        (
           [order_id] => 41111909
           [shop_id] => 34277
           [user_id] => 42363
           [status_id] => 4
         )
)

after use foreach output like this

Array
(
    [41111909] => Array
        (
           [order_id] => 41111909
           [shop_id] => 34277
           [user_id] => 42363
           [status_id] => 4
         )
)
            

How to solve it ?

  • https://stackoverflow.com/questions/65947307/argument-1-parser-must-be-passed-by-reference maybe that will help – Zurupupz Oct 19 '21 at 15:30
  • *"Of course, I can use this code instead that but maybe slower than array_map"* I think this is false. – AymDev Oct 19 '21 at 15:32
  • Your alternative code doesn't seem to actually do the same thing - it looks up 'order_id' on each item. It would be equivalent to `array_map(fn($item) => $item[0]['order_id'], $orders->result)`. I also agree with AymDev that it's not particularly likely to be slow. – IMSoP Oct 19 '21 at 15:36
  • Did you give up? – AbraCadaver Oct 20 '21 at 02:55
  • 1
    Your latest edit is **even more** confusing: it's not the result that **either** of the versions of the code you showed would give. I would strongly recommend stepping back and creating a [mre] - some actual example input and code that you can run on its own. – IMSoP Oct 20 '21 at 12:53
  • Yes the first line and the other code and arrays don't add up, but edited in a solution for the wanted array. – AbraCadaver Oct 20 '21 at 14:11

2 Answers2

4

The simplest replacement is to make an arrow function (single-expression closure) to get the element for you.

If the arrays are plain lists, so that you're always getting element 0, that's as simple as:

$orders->result = array_map(fn($item) => $item[0], $orders->result);

Another alternative in this case is array_column:

$orders->result = array_colum($orders->result, 0);

If you have other keys, you could use either reset or array_key_first in the callback instead:

$orders->result = array_map(fn($item) => $item[array_key_first($item)], $orders->result);

(I suspect array_key_first will be slightly more efficient, since it doesn't need to manipulate the internal array pointer.)

IMSoP
  • 89,526
  • 13
  • 117
  • 169
1

It's not entirely clear what you're trying to do, but it seems like you are trying to get the first value from nested arrays. You should be able to use a function:

$orders->result = array_map(function($v) { return reset($v); }, $orders->result);

You may also try using current if it does what you need as it doesn't take a reference and the array pointer should already be reset by array_map:

$orders->result = array_map('current', $orders->result);

After the edit the code in question is not re-indexing the array as you show in the before and after. To do that is simple:

$orders->result = array_column($orders->result, null, 'order_id');
AbraCadaver
  • 78,200
  • 7
  • 66
  • 87