php中foreach使用引用的陷阱

 

有時候我們爲了在循環過程中改變數組項的值,在foreach的時候變量入口可以加個&符合,

表示,循環過程中使用數組中原來的值,而不是一個複製的值,如

1

foreach ($array as &$item) {}

  

這樣一來,我們在循環中修改$item的值的時候,實際上修改的是$array中對應的值,

而如果不加&符號的話,在循環中修改$item的值不會影響到$array。

 

例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

$array = [

    'name' => 'Jobs',

    'age'  => 50,

];

 

foreach ($array as $key => $value) {

    $value = 22;

}

print_r($array);

 

foreach ($array as $key => &$value) {

    $value = 22;

}

print_r($array);

  

輸出:

Array
(
    [name] => Jobs
    [age] => 50
)
Array
(
    [name] => 22
    [age] => 22
)

=============================================================================

 

陷阱:兩次循環使用同樣的臨時變量的情況下,如果第一次循環使用的是引用,

那麼在第二次循環中即使沒有加&符號,臨時變量也是引用。

這個引用指向了數組中最後一個元素(循環到了最後一個元素結束)。

 

例子:

1

2

3

4

5

6

7

8

9

10

11

12

$array = [

    'name' => 'php',

    'age' => 123,

];

 

foreach ($array as $key => &$value) {

    echo "key=$key, value=$value" . PHP_EOL;

}

 

foreach ($array as $key => $value) {

    echo "key=$key, value=$value" . PHP_EOL;

}

  輸出:

1

2

3

4

key=name, value=php

key=age, value=123

key=name, value=php

key=age, value=php

  

 上面最後一行的value是"php",並不是我們期望的123,這是因爲,在第二個foreach循環中,

每一次循環的時候,都修改了$array中的key爲'age'的值,

第一次循環的時候,數組中的age就已經是php(第一個值)了,在後續的循環中會依次改變數組中最後一個值,

到最後一次循環的時候,取得的值是prev($array),也就是php了。

 

如何避免這個問題?

1、在第二次循環之前,unset($value)

2、第二次foreach的時候使用不同名字的變量,如$item

 

另:查看一個變量是否是引用可以使用xdebug_debug_zval函數(需要有xdebug擴展)。

xdebug_debug_zval的結果形如:

value: (refcount=2, is_ref=1)=123

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章