Auf der Migration auf PHP 7.4 Ich habe mit einem anderen Verhalten einiger Array - Funktionen wie zu behandeln reset()
, current()
oder end()
über Arrayobject. Das folgende Beispiel erzeugt verschiedene Ausgaben:
<?php
$array = new \ArrayObject(["a", "b"]);
$item = end($array);
var_dump($item);
$array = ["a", "b"];
$item = end($array);
var_dump($item);
Mit PHP 7.4 ist die Ausgabe:
bool(false)
string(1) "b"
In PHP-Versionen vor 7.4 lautet die Ausgabe wie folgt:
string(1) "b"
string(1) "b"
A end($array->getArrayCopy())
erzeugt einen Hinweis, kann jedoch eine Problemumgehung sein, wenn es mit einer Variablen verwendet wird.
Gibt es eine Möglichkeit, das Verhalten von end()
mit einem ArrayObject
oder zu emulieren ArrayIterator
? Das ArrayObject kann sehr groß sein, eine Iteration bis zum Ende ist möglicherweise nicht die beste Lösung.
$item = $array[count($array)-1];
. Ich bin mir nicht sicher, ob dies die effizienteste Lösung ist.Antworten:
Ab PHP 7.4 Array-Methoden nicht mit internen Arrays, sondern mit sich
ArrayObject
selbst. Ich habe zwei Lösungen dafür zusammengefasst.1. Internes Array von Objekten abrufen.
2. Erstellen einer Fassade
ArrayObject
und Hinzufügen einer benutzerdefinierten Methode end () zur aktualisierten Klasse.quelle
Sie können das Array-Objekt zu einem Array machen, um die Schlüssel abzurufen, und dann das Ende der Schlüssel verwenden, um den letzten Schlüssel abzurufen.
Es ist keine schöne Lösung, aber es funktioniert.
Ich schlage vor, Sie machen es zu einer Funktion, damit Sie es bei Bedarf aufrufen können.
https://3v4l.org/HTGYn
Als eine Funktion:
quelle
array_keys()
Lösung mit 3v4l.org/IaEMM/perf#output getestet, aber sie benötigte 20-30% mehr Speicher alsend()
auf einem einfachengetArrayCopy()
3v4l.org/uYv59/perf#outputend
können Sie eine Wrapper-Klasse erstellen,ArrayAccess
die eine zusätzliche Funktion implementiert und hat, die einend
internes privates Array zurückgibt , das betrieben werden würde.array_keys
? Warum wirfst du es nicht einfach direkt$arr = (array) $array
und dann$end = end($arr)
Ein etwas schnellerer Ansatz ohne Casting oder Verwendung eines Iterators wäre, den Konstruktor nicht an erster Stelle zu verwenden, sondern eine
append
Methode zu verwenden, mit der ein Array selbst erstellt wird und die Sieend
später für dieses Array verwenden könnencount($array) - 1
Falls Sie später ein anderes Array anhängen, stellen wir sicher, dass dies$item
immer das letzte Element im zuletzt angehängten Array ist.quelle
count()
könnte in einigen Fällen hilfreich sein, aber Ihr Beispiel würde für so etwas nicht funktionierennew \ArrayObject([123 => "a", 456 => "c"]);
append
anstelle des Konstruktors verwendet habe. Die Verwendung von append mit Ihrem Beispiel wird definitiv funktionieren.$array->append([123 => "a", 456 => "c"]
count
nicht für die Elemente Ihres Arrays gilt, sondern für das mehrdimensionale Array,append
das erstellt wird. Für Ihr Array verwenden wirend
wie gewohnt.append()
, könnte ich einecount()
gültige Lösung verwenden. Das könnte mitappend('a')
und funktionierenappend('b')
. Der Schlüssel wäre, assoziative Arrays nicht zuzulassen, was durch die Erweiterung von ArrayObject möglich ist.