2012-03-07 26 views
4

我有兩個功能PHP忽略通過引用傳遞,如果VAR在函數調用分配

function c(&$x) 
{ 
    $x = 25; 
    echo 'c is called, x = ' . $x . PHP_EOL; 
} 

function b() 
{ 
    echo 'b is called'. PHP_EOL; 
    return 5; 
} 

然後我寫了下面的代碼,因爲我想到應該把)B的結果(以$ O,再通過$ o通過引用c()將其設置爲新值。它的工作原理確定:

$o=b(); 
c($o); 
echo 'o is '.$o; 

的輸出爲預期:

b is called 
c is called, x = 25 
o is 25 

但是,如果我嘗試在函數調用這樣分配的$ O值:

c($o = b()); 
echo 'o is '.$o; 

我變得怪異輸出

b is called 
c is called, x = 25 
o is 5 

函數的順序ca lls仍然是一樣的,但是爲什麼$ o沒有改變,儘管它是通過引用傳遞的?如果在函數調用中賦值,PHP是否強制性地通過值傳遞參數?如果是的話,那麼這個版本是以這種方式工作的?根據這個評論:2006年的http://www.php.net/manual/en/functions.arguments.php#71198它的工作方式不同。我的版本是5.3.6

+0

試試這個$ o = c(b()); – 2012-03-07 12:42:45

+2

隨着最大error_reporting,我有'嚴格的標準:只有變量應通過引用傳遞與您的第二個版本。 – 2012-03-07 12:46:43

+0

謝謝。忘了嚴格。但無論如何,這樣的代碼已經在以前的PHP版本中工作。也許我必須檢查最新PHP版本的更新日誌。 – Miroshko 2012-03-07 12:59:21

回答

3

這是Zend引擎的一個限制,即我所遇到前使用socket_select()/stream_select(),這都需要參數「資源陣」通過引用傳遞時尤爲如此。能夠在一行中分配要通過引用傳遞的變量的值是很好的,但它不是(當前)可以實現的。

我已經看到了(雖然現在我找不到在哪裏,(這是here),它可能沒有權威性反正 ),在PHP的任何表達式求的右側前面提到的表達方式。我的意思是:

$a = 1; 
$b = 2; 
echo $a = $b; 

這將呼應2,因爲這是通過echo語句中的表達式計算表達式$b,這是2的右側。

當通過表達一個函數的結果,如c($o = b());,你是路過的$o = b();的功能c()的結果,這是我的理解(雖然我可能是錯的),該表達式的結果傳遞進入函數並執行該函數,之前 a zval被創建並分配爲保存$o,這種行爲旨在減少內存消耗並加速內部處理,當函數以這種方式嵌套時。這意味着你實際上沒有通過引用傳遞變量,你只需傳入由表達式右邊的b()產生的值 - 由於它沒有變量容器,因此無法通過引用修改該值。

事實上,如果你打開E_STRICT消息,您會看到以下錯誤:

Strict Standards: Only variables should be passed by reference in ...

...所以這種行爲實際上是在「設計」。

+4

*設計*自PHP 5.0.5開始,以避免內存損壞。 [來源](http://the-stickman.com/web-development/php/php-505-fatal-error-only-variables-can-be-passed-by-reference/) – 2012-03-07 12:55:39

+0

@GuillaumePoussel感謝您的確認並且很好的挖掘這些信息:-D – DaveRandom 2012-03-07 13:01:42