2011-08-22 269 views
4

我要「按引用傳遞」給我們的實習生解釋之間的差異,在PHP「按值傳遞」,並做了這個簡單的腳本:PHP通過引用傳遞/值 - 問題

$a=5; 
$b=&$a; 
$a=8; 
echo $b; 
// prints 8 
$a=5; 
$b=$a; //no & 
$a=8; 
echo $b; 
// prints 5 

然而,使用PHP -qa產量在PHP-CLI運行以下命令:

php >  $a=5; 
php >  $b=&$a; 
php >  $a=8; 
php >  echo $b; 
8 
php >  // prints 8 
php >  $a=5; 
php >  $b=$a; //no & 
php >  $a=8; 
php >  echo $b; 
8 
php >  // prints 5 

應該不是$b=$a;取消鏈接$ a和$ b?

...所以我就curius,並嘗試:

php > $b=3; 
php > echo $a; 
3 

那麼,爲什麼我得到這個錯了嗎?這裏發生了什麼?看起來參考設置有點困難,即使它應該在行$b=$a清除?我也試過:

php > $e=5; $f=$e; $e=6; echo $f; 
5 

...其中按預期工作。

$a$b似乎永久鏈接?我在這裏錯過了一些重點嗎?如何「取消鏈接」$a$b變量?

+0

你試過'未設置($ b)'在第二部分之前? –

+0

如果您沒有明確表示相同的範圍,請不要在相同範圍內重用變量名稱。 – hakre

+3

+1,因爲這個問題顯示瞭如何試圖向新手解釋一些東西可以幫助你更好地理解它。 – Arkh

回答

6

如果給變量賦值,爲什麼應該清除引用?它的工作原理是這樣的(半簡化的註釋):

$a = 5; // creates a "slot", puts 5 in it, makes $a point to it 
$b =& $a; // makes $b point to the same "slot" $a points to 
$c = 6; // creates a "slot", puts 6 in it, makes $c point to it 
$a = $c; // puts the value of the slot $c points to into the slot $a points to 
echo $b; // outputs the value of the slot $b points to (6) 

它分配一個變量。無論值爲,文字5)還是其他變量所持有的值均無關緊要。該參考文件一直保留至unset($b)

+0

感謝這裏的許多評論:)你的解釋是非常好的欺騙。我認爲(顯然是不正確的)$ b = $ a會爲$ b創建一個新的槽,並帶有$ a的值副本,但我現在看到這可能會非常不夠高效。 還是謝謝! Jonas – jonasfh

+0

@user效率並不是真正的問題,而是它在邏輯上應該如何工作。 – deceze

1

嗯,是的,因爲你創建了$b作爲參考$a。所以,你做一下就行了:

$b = $a 

只是分配5到$一個,因爲$b仍然引用$a

如果您想'重新引用'它,您必須unset並重新創建該變量。

0

您的代碼首次使用$ b時,會創建變量$ b並將其鏈接到$ a的位置。隨後您將值寫入共享位置。您無法撤消變量引用的位置。

+0

撤消:'unset()'。 – hakre

0

繼續我的評論...我跑你的腳本 - 它確實在兩種情況下輸出'8'。我在第一個echo之後加了unset($b)並再次運行 - 現在的輸出爲85,如預期的那樣。

0

問題是,當你做$b = $a,因爲$ b是對$ a的引用,你實際上在做$a = $a。正如其他人告訴的那樣,您必須登錄unset($b)

0

可能使用更多的講的變量名稱使這更清楚你:

$value = 5; 
$alias = &$value; 
$value = 8; 
echo $alias; # 8 
$value = 5; 
$alias = $value; # no & 
$value = 8; 
echo $alias; # 8 (OP expected 5) 

這是更容易閱讀,對不對?

記事尤其是在這條線:

$alias = $value; # no & 

是什麼發生在這裏?

由於$alias是一個別名$value,你基本上可以寫:

$value = $value; 

這是5在這個階段。

然後,設置$value到8

$alias仍參照$value

如果你想停止$alias是一個別名$value,你可以把它變成一個別名別的東西:

$alias = &$other; 

或者正好被清除參考:

unset($alias);