Pada migrasi ke PHP 7.4 saya harus berurusan dengan perilaku yang berbeda dari beberapa fungsi array seperti reset()
, current()
atau end()
mengenai ArrayObject. Contoh berikut menghasilkan output yang berbeda:
<?php
$array = new \ArrayObject(["a", "b"]);
$item = end($array);
var_dump($item);
$array = ["a", "b"];
$item = end($array);
var_dump($item);
Dengan php 7.4 hasilnya adalah:
bool(false)
string(1) "b"
Pada versi PHP sebelum 7.4 output adalah sebagai berikut:
string(1) "b"
string(1) "b"
A end($array->getArrayCopy())
menghasilkan pemberitahuan, tetapi mungkin merupakan solusi jika digunakan dengan variabel.
Apakah ada cara untuk meniru perilaku end()
dengan ArrayObject
atau ArrayIterator
? ArrayObject bisa jadi sangat besar, iterasi sampai akhir mungkin bukan solusi terbaik.
$item = $array[count($array)-1];
. Tidak yakin apakah itu solusi yang paling efisien.Jawaban:
Dari PHP 7.4 metode array tidak beroperasi pada array internal, tetapi pada
ArrayObject
dirinya sendiri. Saya merangkum dua solusi untuk itu.1. Mendapatkan array internal objek.
2. Membuat Fasad
ArrayObject
dan menambahkan metode akhir khusus () ke kelas yang ditingkatkan.sumber
Anda dapat membuat arrayobject sebuah array untuk mendapatkan kunci lalu gunakan akhir pada tombol untuk mendapatkan kunci terakhir.
Ini bukan solusi yang cantik tetapi berhasil.
Saya sarankan Anda menjadikannya fungsi sehingga Anda dapat memanggilnya saat dibutuhkan.
https://3v4l.org/HTGYn
Sebagai fungsi:
sumber
array_keys()
solusinya dengan 3v4l.org/IaEMM/perf#output tetapi membutuhkan 20-30% lebih banyak pada memori dibandingkan denganend()
padagetArrayCopy()
3v4l.org/uYv59/perf#outputend
, maka Anda dapat membuat kelas pembungkus yang mengimplementasikanArrayAccess
dan memiliki fungsi tambahan yang mengembalikan sebuahend
array privat internal yang akan dioperasikan.array_keys
? kenapa tidak Anda hanya dilemparkan langsung$arr = (array) $array
dan kemudian$end = end($arr)
Pendekatan yang sedikit lebih cepat tanpa casting atau menggunakan iterator adalah untuk tidak menggunakan konstruktor di tempat pertama, dan alih-alih menggunakan
append
metode yang akan membuat array itu sendiri dan Anda dapat menggunakanend
array itu nanticount($array) - 1
jika Anda menambahkan array lain nanti, kami memastikan bahwa$item
selalu elemen terakhir dalam array ditambahkan terakhir.sumber
count()
mungkin membantu dalam beberapa kasus, tetapi contoh Anda tidak akan bekerja untuk sesuatu seperti ininew \ArrayObject([123 => "a", 456 => "c"]);
append
bukannya konstruktor, menggunakan menambahkan dengan contoh Anda pasti akan berhasil.$array->append([123 => "a", 456 => "c"]
count
bukan untuk elemen array Anda, itu untuk array multidimensi yangappend
akan dibuat. Untuk array Anda, kami menggunakanend
seperti biasa.append()
, saya bisa menggunakancount()
, itu adalah solusi yang valid. Itu bisa bekerja denganappend('a')
danappend('b')
. Kuncinya adalah untuk melarang array asosiatif yang merupakan kemungkinan dengan memperluas ArrayObject.