2013-04-06 46 views
6

我想知道爲什麼PHP不會抱怨,當我們引用一個非現有的變量(是一個普通的變量或數組),這是隻是它的方式,或者有什麼我失蹤? 例如,此代碼爲什麼PHP在引用一個不存在的變量時不會抱怨?

<?php 
$t = &$r["er"]; 
var_dump($r); 
?> 

不會引發有關非現有變量的警告。

除此之外的var_dump顯示此:

array(1) { ["er"]=> &NULL } 

&NULL是我沒有意料到,我想我會得到一個簡單的NULL

在此先感謝!

+3

引用未聲明的變量會自動在該範圍內定義其名稱。 – mario 2013-04-06 16:07:17

+0

@MarkBaker:錯了。看到我的答案和/或運行代碼來說服自己。&使所有的區別。 – 2013-04-06 16:22:28

+0

謝謝馬里奧,我明白了! – Melsi 2013-04-06 23:50:07

回答

5

如果PHP解釋器引用var分配的內存爲我服務,PHP將在散列表中創建一個null元素,並使用與您發送並引用它的鍵一樣的鍵。這是通過運行下面的測試可見:

<?php 
$i = 0; 
$arr = []; 
$arrS = null; 
$v = memory_get_peak_usage(); 
for ($i = 0; $i < 150; $i++) { 
    $arrS = &$arr[rand()]; 
} 
$v = memory_get_peak_usage() - $v; 
echo $v; 

直到默認堆大小,PHP將只返回一個額外的0內存使用 - 因爲它仍是分配已經「準備」數組項(PHP保留一些額外的哈希表元素爲空,但爲了性能目的分配)。你可以通過設置它從0到16(這是堆大小!)來看到它。當你超過16時,PHP將不得不分配額外的項目,並且將在i = 17,i = 18等...上這樣做,創建空項目以便引用它們。

P.S:與人們所說的相反,這是不是拋出錯誤,警告或通知。回顧一個沒有引用的空項目 - 會引用不存在的項目。大的巨大差異。

+0

很好的答案! +1。我沒有認出'&'運算符 – hek2mgl 2013-04-06 16:18:45

+0

你在那裏放了一段非常令人印象深刻的代碼,$ i $ 11 $ v回聲零,非常好學習堆,默認大小等。 你的答案的最後一行說這一切,我現在知道這個「&」將導致分配。 這個分配(例如:echo &$var;)出現在echo之前,這就是爲什麼php不會發出抱怨,因爲 它迴應了存在的東西(僅在前一步創建)!謝謝! – Melsi 2013-04-06 23:42:36

1

不會對不存在的變量發出警告。

這是參考文獻的工作原理。 $a = &$b;如果還不存在,則創建$b,以供將來參考。這與通過引用傳遞的參數相同。也許這看起來很熟悉了:

preg_match($pattern, $string, $matches); 

這裏的第三個參數是一個基準參數,從而$matches沒有在方法調用的時候存在,但它會被創建。

那& NULL是我沒有真正預料到的,我想我會得到一個普通的NULL。

你爲什麼不指望它呢? $r['er']是參考「到/從」$t。請注意,引用不是指針,$r['er']$t對同一個值的引用相同,不存在從一個到另一個的方向(因此最後一句中的引號)。

+0

+1這是一個很好的答案先生!特別是當你提到「preg_match」和「沒有方向」時,這個關於方向的信息是我錯過的東西,它已經幫助我深入瞭解事情。不幸的是,我可以接受一個答案,這是不可能的,我選擇兩個答案都比接受,我不得不做回聲蘭特(1,2);爲了選擇,希望我不會因此而受到懲罰!非常感謝你!那個「方向」的東西太好學了! – Melsi 2013-04-06 23:46:22

相關問題