首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在ArrayObject中循环和取消设置时的意外行为。忽略一项。

在ArrayObject中循环和取消设置时的意外行为。忽略一项。
EN

Stack Overflow用户
提问于 2016-10-17 13:17:53
回答 1查看 1K关注 0票数 10

(下面是示例!)

我们刚刚将后端升级到PHP7,之后,我们在与ArrayObject相关的代码中发现了一个bug。

代码只是遍历对象的副本(输入本机ArrayObject)。foreach按值进行迭代。

代码的目的是过滤一些您不需要的值。在本例中,如果迭代值为“2”或“3”,则将其取消。我尝试过使用迭代器,而不是复制的值,而不使用迭代器。

结果:

- Iterator

  • PHP 5.6:按预期工作,返回的值是没有值“2”和“3”的数组
  • PHP 7:它只删除“2”,并且似乎没有计算值“3”的项(参见循环中的echo,它没有打印“三”)

- No Iterator

  • PHP 5.6:获得通知,但按预期工作,返回的值是没有值“2”和“3”的数组
  • PHP 7:它只删除“2”,并且似乎没有计算值“3”的项(参见循环中的echo,它没有打印“三”)

第一个循环=> $key = 0,$value = "one“//继续

第二个循环=> $key = 1,$value = " Second“// unset

第三循环=> $key = 3,$value =“4”// WTF?$key = 2,$value =“3”在哪里?

所以我不明白怎么回事。我们的时态解决方案是迭代原始对象并从副本中取消设置。有谁知道PHP核心(或ArrayObject/ArrayIterator)中的哪些更改会造成这种情况呢?我已经对它进行了搜索,但是有些人有这个问题,因为这个问题被重复的项目是参考的。

如果在PHP5.6和7之间切换,行为就会发生变化。

Example 1 (with iterator)

代码语言:javascript
运行
复制
$elements = new ArrayObject();
$elements->append('one');
$elements->append('two');
$elements->append('three');
$elements->append('four');

print_r($elements);

$clone = clone $elements;
$it = $clone->getIterator();

echo "\n------\n";
foreach ($it as $key => $value) {
    echo $key."\t=>\t".$value."\n";
    if ($value == 'two' || $value == 'three') {
        $it->offsetUnset($key);
    }
}
echo "\n------\n";
print_r($clone);

Example 2 (without iterator)

代码语言:javascript
运行
复制
$elements = new ArrayObject();
$elements->append('one');
$elements->append('two');
$elements->append('three');
$elements->append('four');

print_r($elements);

$clone = clone $elements;

echo "\n------\n";
foreach ($clone as $key => $value) {
    echo $key."\t=>\t".$value."\n";
    if ($value == 'two' || $value == 'three') {
        $clone->offsetUnset($key);
    }
}
echo "\n------\n";
print_r($clone);

非常感谢!

EN

回答 1

Stack Overflow用户

发布于 2016-10-17 13:34:20

据我理解,在循环数组的同时修改数组被认为是一种不好的做法,正确的方法是使用array_filter

由于您有一个ArrayObject,一种解决方案是将它导出到一个数组中,使用array_filter对其进行筛选,并从筛选出来的数组中创建一个新的ArrayObject

另见此处:Filter ArrayObject (PHP)

这种行为可能是由于循环在php7中的处理方式不同。如前所述:http://php.net/manual/en/control-structures.foreach.php in php5 foreach使用内部数组指针,而不是php7。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40087458

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档