朋友昨天去金山面試PHP開發時遇到的一道面試題,是關於引用和foreach迴圈的。很基礎的一道題
廢話不多說,直接看代碼:
$a = array('a','b','c');foreach($a as &$v){}foreach($a as $v){}var_dump($a);
現在。不要開啟瀏覽器,猜測一下。輸出的結果是什嗎?
對引用比較瞭解的童鞋可能已經看出來了。正確答案是: array(3) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> &string(1) "b"} 也就是a,b,b. 如果你猜測的是a,b,c的話。 那麼關於引用,你還要查閱一下相關的資料:http://www.php.net/manual/zh/language.references.php
那麼為什麼是a,b,b呢。讓我們一步步來看:
我們知道對數組執行foreach迴圈時,是通過移動數組內部指標來實現的(關於更多細節,可以閱讀php源碼)。因而對於本文中的例子:當foreach迴圈結束的時候,由於$v為
引用變數,因而$v 與 $a[ 2 ] 指向了同一個地址空間(共用變數值),因而之後對$v的任何修改都會直接反映到數組$a中。我們可以對例子加上調試代碼,便會一清二楚,例如我們在第二次迴圈內部,加上var_dump($a),測試每次迴圈時a的值的變化:
$a = array('a','b','c');foreach($a as &$v){}foreach($a as $v){var_dump($a);echo "<br/>";}var_dump($a);
運行代碼。結果為:
array(3) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> &string(1) "a" }array(3) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> &string(1) "b" }array(3) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> &string(1) "b" }array(3) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> &string(1) "b" }
畫個圖:可以更加清晰看出來:(圖中"$v指向了$a[2]"並不準確。應該是:$v與$a[2]指向了同一個地方)
關於引用的幾點簡單解釋:
1.引用類似於指標,但是不同於指標。
例如對於引用:
$a = "str";$b = &$a;// $a 和 $b 指向了同一個地方
一個簡單的如下:
那麼此時更改$a和$b中任何一個元素的值。另外一個值都為隨之改變:
$a = "str";$b = &$a;$b = "sssss";echo $a;
2.unset只會刪除變數。並不會清空變數值對應的記憶體空間:(這是與指標不同的地方)
$a = "str";$b = &$a;unset($b);echo $a;
3.引用作為函數參數傳遞時,是可以被函數內部更改的:
function change(&$a){if(is_array($a)){$a = array();}}$test = range(1,10);change($test);print_r($test);
基於以上幾點,在編碼的過程中,要小心使用引用。防止陷入莫名其妙的尷尬。