PHP 7.4에서 ArrayObject가 end ()와 작동하지 않습니다


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"

7.4 이전의 PHP 버전에서 출력은 다음과 같습니다.

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

A end($array->getArrayCopy())는 통지를 생성하지만 변수와 함께 사용하면 해결 방법이 될 수 있습니다.

행동의 모방 할 수있는 방법이 있나요 end()ArrayObject또는 ArrayIterator? ArrayObject는 매우 클 수 있으며 끝까지 반복하는 것이 최선의 해결책이 아닐 수 있습니다.


대안이 될 수 있습니다 $item = $array[count($array)-1];. 그것이 가장 효율적인 솔루션인지 확실하지 않습니다.
Patrick Q

2
PHP 버그로 인정된다고 말하면, changelog에는 이것이 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 업그레이드 된 클래스에 Facade 생성 및 사용자 정의 메소드 end () 추가.


0

배열 객체를 배열로 만들어 키를 얻은 다음 키의 끝을 사용하여 마지막 키를 얻을 수 있습니다.

$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
3v4l.org/IaEMM/perf#output으로array_keys() 솔루션을 테스트 했지만 간단한 3v4l.org/uYv59/perf#output 과 비교할 때 메모리에서 20-30 % 더 필요end()getArrayCopy()
Trendfischer

1
@Trendfischer 메모리가 문제이고 사용하려는 경우 end에만 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예제와 함께 append를 사용하면 생성자 대신 사용하는 것이 확실히 작동 한다는 것을 알고 있습니다. $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.