On migrating to PHP 7.4 I have to deal with a different behavior of some array functions like reset()
, current()
or end()
concerning ArrayObject. The following example produces different outputs:
<?php
$array = new ArrayObject(["a", "b"]);
$item = end($array);
var_dump($item);
$array = ["a", "b"];
$item = end($array);
var_dump($item);
With php 7.4 the output is:
bool(false)
string(1) "b"
On PHP versions before 7.4 the output is the following:
string(1) "b"
string(1) "b"
A end($array->getArrayCopy())
produces a notice, but might be a workaround if used with a variable.
Is there a way to emulate the behavior of end()
with an ArrayObject
or ArrayIterator
? The ArrayObject could be very big, an iteration to the end might not be the best solution.
4
Answers
You can make the arrayobject an array to get the keys then use end on the keys to get the last key.
It’s not a pretty solution but it works.
I suggest you make it a function so that you can call it when needed.
https://3v4l.org/HTGYn
As a function:
A slightly faster approach without casting or using an iterator would be to not use the constructor in the first place, and instead use
append
method which will create an array itself and you can useend
on that array latercount($array) - 1
in case you append another array later, we make sure that$item
is always the last element in the last appended array.From PHP 7.4 array methods don’t operate on internal array, but on
ArrayObject
itself. I summarized two solutions for that.1. Getting internal array of object.
2. Creating Facade of
ArrayObject
and adding custom method end() to upgraded class.Came up with this approach.
Should perform better than any of the above.