ArrayObject不适用于PHP 7.4中的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()与一个ArrayObjectArrayIterator?ArrayObject可能非常大,到最后的迭代可能不是最佳解决方案。


另一种可能是$item = $array[count($array)-1];。不确定这是否是最有效的解决方案。
Patrick Q

2
我想说这是一个PHP错误,更改日志中绝对没有任何内容可以表明这是7.4中的预期更改
iainn

在线测试:3v4l.org/4MADI
0stone0

1
@PatrickQ如果是关联的怎么办?
安德烈亚斯

4
@iainn这绝对不是一个错误- php.net/manual/en/...
u_mulder

Answers:


2

PHP 7.4开始,数组方法不对内部数组起作用,而是对ArrayObject自身起作用。为此,我总结了两种解决方案。

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

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

2.创建Facade ArrayObject并将自定义方法end()添加到升级的类。


0

您可以将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);

当我查看结果和有问题的usaqe时,我没有看到两个答案之间的区别。如果有差异请解释
Dlk

1
我已经array_keys()使用3v4l.org/IaEMM/perf#output测试了该解决方案,但与end()简单的getArrayCopy() 3v4l.org/uYv59/perf#output
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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.