到目前爲止,我們一直在使用PHP 5.5,並且所有代碼都看起來流暢。由於將其升級到7,大部分foreach()似乎都有不一致的行爲。在PHP 7中處理foreach by-ref
對於例如:考慮下面的代碼段:
$array = array('a', 'b', 'c');
self::testForeach($array);
.
.
.
// $array is passed by reference
public static function testForeach(&$array) {
foreach ($array as $key => $val) {
//produces a, b as an output in PHP 5
//produces a, b, c as an output in PHP 7
var_dump($val);
if ($val == 'b') {
//remove 'c' from the array
unset($array[2]);
}
}
}
行爲在PHP 5.5:
$陣列通過引用傳遞到testForeach()函數。因此,從循環中的$ array中刪除「c」將直接修改原始數組。因此,迭代的值將是a,b,而不是c,因爲它會從中間的數組中移除。
行爲在PHP 7:
$陣列通過引用傳遞到testForeach()函數。當$ array循環遍歷foreach()時,會複製一個副本,說$循環中正在迭代的$ arrayCopy(根據doc)。因此,從$ array中刪除「c」值將不起作用,並會循環$ arrayCopy中包含的所有值。 因此輸出 - a,b,c。
將foreach更改爲pass-by-ref對我來說不是一個解決方案,因爲我的項目中有太多的foreach,我無法grep和修改它們中的每一個。
是否有任何其他處理完成這種行爲在最新版本。任何可以突出顯示它們的工具/解析器?
任何提示/想法?
謝謝!
在迭代它時不要修改數組。它在許多語言中有未定義的行爲。 PHP在兩個版本上都是正確的。迭代輸入數組並將項目複製到新數組中或在需要時跳過它們。 – axiac
你有兩個選擇:1)不要升級到7並修復你的代碼2)升級到7並修復你的代碼 – PeeHaa
@axiac如果我這樣做,有n個地方需要這種處理。我能不能有一個地方(庫等)限制foreach()不改變複製變量的地址(正在迭代),以便它在循環中立即被修改? – jitendrapurohit