ArrayObject 不适用于 PHP 7.4 中的 end()

ArrayObject does not work with end() in PHP 7.4

在迁移到 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()) 会产生一条通知,但如果与变量一起使用可能是一种解决方法。

有没有办法用 ArrayObjectArrayIterator 来模拟 end() 的行为? ArrayObject 可能非常大,迭代到最后可能不是最佳解决方案。

您可以使 arrayobject 成为一个数组来获取键,然后在键上使用 end 来获取最后一个键。

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

不使用强制转换或使用迭代器的稍微快一点的方法是首先不使用构造函数,而是使用 append 方法,该方法将自己创建一个数组,您可以使用 end 稍后在那个数组上

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

count($array) - 1 如果您稍后附加另一个数组,我们确保 $item 始终是最后附加数组中的最后一个元素。

From PHP 7.4 数组方法不对内部数组进行操作,而是对 ArrayObject 本身进行操作。我总结了两个解决方案。

1.获取对象的内部数组。

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

2. 创建 ArrayObject 的门面并添加自定义方法 end() 以升级 class.

想到了这个方法。

应该比以上任何一项都表现得更好。

  • 不使用内存转换为另一个变量 CPU
  • 只有一个内部迭代器。
  • 只有一个新变量,它是对项目的引用。
class MyClass extends ArrayObject {
    public function last() {
        foreach ($this as $entity) {}
        return $entity ?? null;
    }
}

$array = new \MyClass(["a", "b", "c"]);
$item = $array->last();
var_dump($item);