Al migrar a PHP 7.4 tengo que lidiar con un comportamiento diferente de algunas funciones de matriz como reset(), current()o con end()respecto a ArrayObject. El siguiente ejemplo produce diferentes salidas:
<?php
$array = new \ArrayObject(["a", "b"]);
$item = end($array);
var_dump($item);
$array = ["a", "b"];
$item = end($array);
var_dump($item);
Con php 7.4 el resultado es:
bool(false)
string(1) "b"
En las versiones de PHP anteriores a 7.4, el resultado es el siguiente:
string(1) "b"
string(1) "b"
A end($array->getArrayCopy())produce un aviso, pero podría ser una solución si se usa con una variable.
¿Hay alguna manera de emular el comportamiento de end()con un ArrayObjecto ArrayIterator? El ArrayObject podría ser muy grande, una iteración hasta el final podría no ser la mejor solución.

$item = $array[count($array)-1];. No estoy seguro si esa es la solución más eficiente.Respuestas:
Desde PHP 7.4, los métodos de matriz no operan en una matriz interna, sino en
ArrayObjectsí misma. Resumí dos soluciones para eso.1. Obtener una matriz interna de objetos.
2. Crear Fachada de
ArrayObjecty agregar método personalizado end () a la clase actualizada.fuente
Puede convertir el objeto de matriz en una matriz para obtener las claves y luego usar end en las claves para obtener la última clave.
No es una solución bonita pero funciona.
Le sugiero que lo convierta en una función para que pueda llamarlo cuando sea necesario.
https://3v4l.org/HTGYn
Como una función:
fuente
array_keys()solución con 3v4l.org/IaEMM/perf#output pero necesitaba un 20-30% más de memoria en comparación con unend()simplegetArrayCopy()3v4l.org/uYv59/perf#outputend, puede crear una clase de contenedor que implementeArrayAccessy tenga una función adicional que devuelva unaendde la matriz privada interna que se operaría.array_keys? ¿Por qué no lo lanzas directamente$arr = (array) $arrayy luego$end = end($arr)Un enfoque un poco más rápido sin convertir o usar un iterador sería no usar el constructor en primer lugar, y en su lugar usar un
appendmétodo que creará una matriz en sí misma y que puede usarenden esa matriz más tardecount($array) - 1en caso de que agregue otra matriz más tarde, nos aseguramos de que$itemsiempre sea el último elemento en la última matriz agregada.fuente
count()podría ser útil en algunos casos, pero su ejemplo no funcionaría para algo como estonew \ArrayObject([123 => "a", 456 => "c"]);appendlugar del constructor, usar append con tu ejemplo definitivamente funcionará.$array->append([123 => "a", 456 => "c"]countque no es para los elementos de su matriz, es para la matriz multidimensional queappendcreará. Para su matriz estamos utilizandoendcomo de costumbre.append(), podría usar unacount()solución válida. Eso podría funcionar conappend('a')yappend('b'). La clave sería no permitir matrices asociativas, que es una posibilidad al extender ArrayObject.