php foreach面试题,PHP引用理解之神奇的foreach面试题
最近面試了一些各種背景的同學,發現下面這題鮮有人答出來。題目看起來刁鉆,實際上是對引用很好的考察。
一、題目和答案
題目如下(要求寫出兩次輸出的結果):
$value = ['foo', 'bar', 'cat'];
foreach($value as &$val) {
// nothing to do
}
var_dump($value);
foreach($value as $val) {
// also nothing to do
}
var_dump($value);
// the end of the script
如果你不確定,可以直接告訴你答案,如下:
array(3) {
[0]=>
string(3) "foo"
[1]=>
string(3) "bar"
[2]=>
&string(3) "cat"
}
array(3) {
[0]=>
string(3) "foo"
[1]=>
string(3) "bar"
[2]=>
&string(3) "bar"
}
如果有興趣,建議暫停,自己揣摩下原因。
然后繼續往下
二、理論解答
0、先說引用
我理解PHP中的引用是不同的變量名訪問同一個變量內容,或者說指向同一塊內存地址。
可以類比Linux中的軟連接來理解
ln -s 源文件 目標文件
1、再說數組
如果你通讀過PHP官方手冊foreach章節的話,應該很熟悉,PHP foreach遍歷數組是通過數組內部指針移動來實現,foreach開始時數組內部指針會自動指向第一個單元,每次循環中當前單元的值會賦給as后面的變量,同時數組內部指針會往前移動一步。
Warning 數組最后一個元素的 $value 引用在 foreach 循環之后仍會保留。建議使用 unset() 來將其銷毀。
$value = ['foo', 'bar', 'cat'];
foreach($value as &$val) {
// nothing to do
}
$val = 'salmonl';
var_dump($value);
所以上面的代碼會輸入下面的內容
array(3) {
[0]=>
string(3) "foo"
[1]=>
string(3) "bar"
[2]=>
&string(7) "salmonl"
}
上面這句話太重要了(來自手冊后面的評論留言)
“Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset().”
I cannot stress this point of the documentation enough!!!
三、實際解惑
理解了上面這一步,這一題基本理解了60%。這道題神奇的地方在于,兩次foreach循環使用了同一個數組變量。所以在第二次foreach的時候,$val一直改表著整個數組
第二次foreach循環三次
0、第一次循環借宿
$value = [‘foo’, ‘bar’, ‘foo’];
1、第二次
$value = [‘foo’, ‘bar’, ‘bar’];
這一步對理解尤其關鍵,因為$value[2] = ‘bar’, 所以數組內部指針移動到第三個單元的時候,內容已經是’bar’了
2、第三次
$value = [‘foo’, ‘bar’, ‘bar’];
四、思考
在以往的工作經歷中,發現身邊的很多同事對引用掌握的不牢,使用引用導致了很多動態問題。反思了下注意有2點原因
0、對引用理解不深入,不參考手冊說明開發。手冊明確說了需要unset()。
1、定義變量名的隨意性。foreach的時候不加區分的用$k => $v,很容易埋下禍患。
這個問題的解決辦法很多,參考
0、第一次foreach后unset($val)。
1、as后面不都使用$val。
五、參考
如果還是一頭霧水,推薦讀讀這篇詳細的分析文章《對數組兩次foreach的使用陷阱》,寫的是真的好。
總結
以上是生活随笔為你收集整理的php foreach面试题,PHP引用理解之神奇的foreach面试题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php usort strcmp,字符串
- 下一篇: matlab中antoine方程应用,A