ArrayObject ไม่ทำงานกับ end () ใน PHP 7.4


9

เกี่ยวกับการย้ายไป PHP 7.4 ผมต้องจัดการกับพฤติกรรมที่แตกต่างกันของฟังก์ชั่นบางอย่างเช่นอาร์เรย์reset(), current()หรือend()เกี่ยวกับ ArrayObject ตัวอย่างต่อไปนี้สร้างเอาต์พุตที่ต่างกัน:

<?php

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


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

ด้วยphp 7.4ผลลัพธ์คือ:

bool(false)
string(1) "b"

ในเวอร์ชัน PHP ก่อนหน้า 7.4 ผลลัพธ์จะเป็นดังนี้:

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

A end($array->getArrayCopy())สร้างการแจ้งเตือน แต่อาจเป็นการแก้ไขหากใช้กับตัวแปร

มีวิธีที่จะเลียนแบบพฤติกรรมของที่end()มีสระArrayObjectหรือArrayIterator? ArrayObject อาจมีขนาดใหญ่มากการทำซ้ำไปจนสุดอาจไม่ใช่ทางออกที่ดีที่สุด


$item = $array[count($array)-1];ทางเลือกที่อาจจะ ไม่แน่ใจว่าเป็นทางออกที่มีประสิทธิภาพที่สุดหรือไม่
Patrick Q

2
ฉันบอกว่ามีคุณสมบัติเป็นข้อผิดพลาด PHP ไม่มีอะไรแน่นอนในการเปลี่ยนแปลงที่จะแนะนำว่านี่คือการเปลี่ยนแปลงที่ตั้งใจใน 7.4
iainn

ทดสอบออนไลน์: 3v4l.org/4MADI
0stone0

1
@PatrickQ เกิดอะไรขึ้นถ้ามันเชื่อมโยงกัน?
Andreas

4
@iainn นี่ไม่ใช่ข้อผิดพลาดแน่นอน - php.net/manual/en/…
u_mulder

คำตอบ:


2

จากวิธีการต่างๆของPHP 7.4นั้นไม่สามารถใช้งานกับอาเรย์ภายในArrayObjectได้ ฉันได้สรุปวิธีแก้ปัญหาสองข้อสำหรับเรื่องนั้น

1.การหาอาร์เรย์ภายในของวัตถุ

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

2.การสร้างซุ้มArrayObjectและการเพิ่มเมธอดแบบกำหนดเอง () ลงในคลาสที่อัปเกรดแล้ว


0

คุณสามารถสร้าง arrayobject ให้กับ array เพื่อรับกุญแจจากนั้นใช้ปุ่มท้ายเพื่อรับคีย์สุดท้าย

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

var_dump($array[$end_key]);

มันไม่ใช่ทางออกที่ดี แต่ใช้งานได้
ฉันแนะนำให้คุณใช้ฟังก์ชั่นเพื่อให้คุณสามารถเรียกมันได้เมื่อต้องการ

https://3v4l.org/HTGYn

ในฐานะที่เป็นฟังก์ชั่น:

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);

ฉันไม่เห็นความแตกต่างระหว่างคำตอบทั้งสองเมื่อฉันดูผลลัพธ์และ usaqe ที่เป็นปัญหา หากความแตกต่างอธิบายโปรด
Dlk

1
ฉันได้ทดสอบarray_keys()โซลูชันด้วย3v4l.org/IaEMM/perf#outputแต่ต้องการหน่วยความจำเพิ่มขึ้น 20-30% เมื่อเทียบกับ3v4l.org/uYv59/perf#outputend()แบบธรรมดาgetArrayCopy()
Trendfischer

1
@Trendfischer หากหน่วยความจำเป็นปัญหาและหากคุณต้องการใช้endเท่านั้นคุณสามารถสร้างคลาส wrapper ที่ใช้งานArrayAccessและมีฟังก์ชั่นเพิ่มเติมซึ่งจะคืนค่าendอาร์เรย์ส่วนตัวภายในที่จะใช้งาน
vivek_23

1
@ vivek_23 ฟังดูเหมือนคำตอบที่ดี
Trendfischer

3
คำถาม: มีจุดประสงค์array_keysอะไร? ทำไมคุณไม่เพียงแค่โยนมันโดยตรง$arr = (array) $arrayจากนั้น$end = end($arr)
เรน

0

วิธีที่เร็วกว่าเล็กน้อยโดยไม่ใช้การคัดเลือกหรือใช้ตัววนซ้ำจะไม่ใช้ตัวสร้างในตอนแรกและใช้appendวิธีการที่จะสร้างอาร์เรย์เองแทนและคุณสามารถใช้endกับอาร์เรย์นั้นในภายหลัง

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

count($array) - 1ในกรณีที่คุณต่อท้ายอาร์เรย์อื่นในภายหลังเราตรวจสอบให้แน่ใจว่า$itemเป็นองค์ประกอบสุดท้ายเสมอในอาร์เรย์ที่ผนวกท้ายล่าสุด


1
ขอบคุณวิธีแก้ปัญหาcount()อาจมีประโยชน์ในบางกรณี แต่ตัวอย่างของคุณไม่สามารถใช้งานได้เช่นนี้new \ArrayObject([123 => "a", 456 => "c"]);
Trendfischer

@Trendfischer ฉันรู้ว่านั่นเป็นสาเหตุที่ฉันใช้appendแทน Constructor การใช้ผนวกกับตัวอย่างของคุณจะทำงานได้อย่างแน่นอน $array->append([123 => "a", 456 => "c"]
ฝนตก

@Trendfischer โปรดทราบcountว่าไม่ได้มีไว้สำหรับองค์ประกอบของอาเรย์ของคุณสำหรับอาเรย์หลายมิติที่appendจะสร้าง สำหรับชุดของคุณเราใช้endตามปกติ
ฝนตก

1
ฉันซาบซึ้งในความตั้งใจ แต่ฉันมักจะไม่ใช้ ArrayObject เป็นวิธีการแทนที่แบบง่ายสำหรับอาร์เรย์ ตัวอย่างในคำถามเป็นแบบอย่างเพื่อแสดงปัญหา แม้ว่าฉันจะใช้append()แต่ฉันสามารถใช้count()นั่นเป็นวิธีแก้ปัญหาที่ถูกต้อง ที่สามารถทำงานร่วมกับและappend('a') append('b')กุญแจสำคัญคือการไม่อนุญาตให้เชื่อมโยงอาร์เรย์ซึ่งเป็นไปได้โดยการขยาย ArrayObject
Trendfischer
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.