ArrayObject PHP 7.4'te end () ile çalışmaz


9

PHP 7.4'e geçiş yaparken reset(), ArrayObject gibi current()ya da end()ArrayObject ile ilgili bazı dizi işlevlerinin farklı bir davranışıyla uğraşmak zorundayım . Aşağıdaki örnek farklı çıktılar üretir:

<?php

$array = new \ArrayObject(["a", "b"]);
$item = end($array);
var_dump($item);


$array = ["a", "b"];
$item = end($array);
var_dump($item);

İle php 7.4 çıktısı:

bool(false)
string(1) "b"

7.4'ten önceki PHP sürümlerinde çıktı aşağıdaki gibidir:

string(1) "b"
string(1) "b"

A end($array->getArrayCopy())bir uyarı oluşturur, ancak bir değişkenle kullanılırsa geçici bir çözüm olabilir.

end()Bir ArrayObjectveya ile davranışını taklit etmenin bir yolu var mı ArrayIterator? ArrayObject çok büyük olabilir, sonuna kadar bir yineleme en iyi çözüm olmayabilir.


Bir alternatif olabilir $item = $array[count($array)-1];. Bunun en verimli çözüm olup olmadığından emin değilim.
Patrick Q

2
Ben bir PHP hata olarak nitelendirdi söyleyebilirim, kesinlikle 7.4 içinde amaçlanan bir değişiklik olduğunu önerecek hiçbir şey yoktur
iainn

Çevrimiçi test edin: 3v4l.org/4MADI
0stone0

1
@PatrickQ ya ilişkiliyse?
Andreas

4
@iainn bu kesinlikle bir hata değil - php.net/manual/en/…
u_mulder

Yanıtlar:


2

Gönderen PHP 7.4 dizi yöntemleri iç dizisinde çalışır ancak üzerinde değil ArrayObjectkendisi. Bunun için iki çözüm özetledim.

1. Nesnenin dahili dizisini alma.

$array = new \ArrayObject(["a", "b"]);
$item = end($array->getArrayCopy());

2. Cephe Oluşturma ArrayObjectve yükseltilmiş sınıfa özel yöntem end () ekleme.


0

Dizi nesnesini anahtarları almak için bir dizi yapabilir ve ardından son anahtarı almak için anahtarların sonunu kullanabilirsiniz.

$array = new \ArrayObject(["a", "b"]);
$keys = array_keys((array)$array);
$end_key = end($keys);

var_dump($array[$end_key]);

Güzel bir çözüm değil ama işe yarıyor.
Gerektiğinde çağırabilmeniz için bir işlev yapmanızı öneririm.

https://3v4l.org/HTGYn

İşlev olarak:

function end_object($array){
    $keys = array_keys((array)$array);
    $end_key = end($keys);
    return $array[$end_key];
}


$array = new \ArrayObject(["a", "b"]);
$item = end_object($array);
var_dump($item);

Sonuca ve söz konusu usaqe'ye baktığımda her iki cevap arasında fark görmüyorum. fark lütfen açıklayın
20:20

1
Ive'sınav array_keys()ile çözüm 3v4l.org/IaEMM/perf#output ancak 20-30% daha belleğe bir kıyasla gerekli end()bir basit üzerine getArrayCopy() 3v4l.org/uYv59/perf#output
Trendfischer

1
@Trendfischer Bellek sorunu varsa ve endyalnızca kullanmak istiyorsanız , o zaman bir sarıcı sınıf oluşturabilir ArrayAccessve endçalıştırılacak bir iç özel dizi döndüren ek bir işleve sahip olabilirsiniz.
vivek_23

1
@ vivek_23 iyi bir yanıt gibi geliyor
Trendfischer

3
Soru: amacı array_keysnedir? neden sadece doğrudan döküm yok $arr = (array) $arrayve sonra$end = end($arr)
Yağmur

0

Bir yineleyici kullanmadan veya bir yineleyici kullanmadan biraz daha hızlı bir yaklaşım, yapıcıyı ilk etapta kullanmamak ve bunun yerine appendbir dizinin kendisini oluşturacak ve enddaha sonra bu dizi üzerinde kullanabileceğiniz bir yöntem kullanmak olacaktır.

$array = new \ArrayObject();
$array->append(["a", "b"]);
$item =  end($array[count($array) - 1]);
var_dump($item);

count($array) - 1daha sonra başka bir dizi eklerseniz $item, her zaman son eklenen dizideki son öğe olduğundan emin oluruz .


1
Teşekkürler, ile çözüm count()bazı durumlarda yardımcı olabilir, ancak örneğin böyle bir şey için işe yaramaznew \ArrayObject([123 => "a", 456 => "c"]);
Trendfischer

@ Trendfischer Bu yüzden appendyapıcı yerine kullandığımı biliyorum, örneğinizle append kullanmak kesinlikle işe yarayacak. $array->append([123 => "a", 456 => "c"]
Yağmur

@Trendfischer Lütfen countdizinizin elemanları için değil append, oluşturacağınız çok boyutlu dizi için olduğunu unutmayın . Diziniz için endher zamanki gibi kullanıyoruz .
Yağmur

1
Niyeti takdir ediyorum, ama genellikle bir dizi için basit bir yedek olarak bir ArrayObject kullanmıyorum. Sorudaki örnek sorunu göstermek için örnek niteliğindedir. Ben sadece kullanırsanız rağmen append(), ben kullanabilir count(), o geçerli bir çözümdür. Bu append('a')ve ile çalışabilir append('b'). Anahtar, ArrayObject öğesini genişleterek bir olasılık olan ilişkilendirilebilir dizilere izin vermemek olacaktır.
Trendfischer
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.