(下面是示例!)
我们刚刚将后端升级到PHP7,之后,我们在与ArrayObject相关的代码中发现了一个bug。
代码只是遍历对象的副本(输入本机ArrayObject)。foreach按值进行迭代。
代码的目的是过滤一些您不需要的值。在本例中,如果迭代值为“2”或“3”,则将其取消。我尝试过使用迭代器,而不是复制的值,而不使用迭代器。
结果:
- Iterator
- No Iterator
第一个循环=> $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)
$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)
$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);非常感谢!
发布于 2016-10-17 13:34:20
据我理解,在循环数组的同时修改数组被认为是一种不好的做法,正确的方法是使用array_filter。
由于您有一个ArrayObject,一种解决方案是将它导出到一个数组中,使用array_filter对其进行筛选,并从筛选出来的数组中创建一个新的ArrayObject。
这种行为可能是由于循环在php7中的处理方式不同。如前所述:http://php.net/manual/en/control-structures.foreach.php in php5 foreach使用内部数组指针,而不是php7。
https://stackoverflow.com/questions/40087458
复制相似问题