2017-07-06 179 views
-1

我有以下代碼:PHP 7:通過引用傳遞非變量以及爲什麼通知如果函數通過,但是如果數組通過時發生致命錯誤?

$family = cis_resempty(wp_get_post_terms($post->ID,'family'),0); 

我收到以下錯誤:

Notice: Only variables should be passed by reference in C:\xampp.....xxx.php on line 18

如果我做了以下內容:

$family = cis_resempty(array('a'),0); 

我甚至得到

Fatal error: Only variables can be passed by reference in C:\xampp...xxx.php on line 16

功能cis_resempty是這樣的(但其從庫):

function cis_resempty(&$var,$key) { ... } 

發現,如果我刪除cis_resempty的參數列表中的&符號沒有錯誤。

如果我這樣做:

$family = @cis_resempty(wp_get_post_terms($post->ID,'family'),0); 

沒有通知,一切工作 - 但Netbeans的說:

Misuse of the error control operator

但是,如果我這樣做:

$family = @cis_resempty(array('a'),0); 

致命錯誤仍然存​​在。

爲什麼我可以通過引用傳遞一個函數,並使用錯誤控制運算符來抑制通知,但是如果我傳遞一個數組,我會得到一個致命錯誤?

爲什麼通過引用傳遞非變量很糟糕?

回答

2

術語「非可變」是指程序員不能按名稱引用的任何變量。這些是執行程序在運行時分配的臨時變量:函數調用或其他表達式的結果,它不會被分配給命名變量。

按引用傳遞的東西纔有意義,如果按引用傳遞的變量被命名,這樣,當通話結束後,主叫方可以訪問其被引用到被叫方通過。

當PHP遇到在編譯時一個函數調用,該函數調用的結果參數的函數調用的空間,並且被保留,然後在時間相對於所述執行幀執行分配。當您通過引用傳遞一個函數調用的結果,執行者能夠迫使通過引用行爲變量,因爲在堆空間,它可以忽略的變量沒有名字......它不」通常這樣做是有道理的,但仍然是出於向後兼容的原因。

當PHP遇到一個文字(數組)在編譯時,它分配用於相對於所述運算陣列(功能)本身的數據的空間。因爲這種差異迫使被引用文字的行爲將是危險的,會導致非常意外的行爲:考慮重新進入函數時會發生什麼,同時或以其他方式。

3

注意:從來沒有使用'@'抑制。

Why can I pass a function by reference and suppress the notice with the error control operator but if I pass an array I get a fatal error?

這裏閱讀Passing by Reference第一個音符:

There is no reference sign on a function call - only on function definitions. Function definitions alone are enough to correctly pass the argument by reference. As of PHP 5.3.0, you will get a warning saying that "call-time pass-by-reference" is deprecated when you use & in foo(&$a);. And as of PHP 5.4.0, call-time pass-by-reference was removed, so using it will raise a fatal error.

PHP不 「支持」 它,因爲5.4.0 =>你在任何情況下​​。用@或不用@。對於功能 - 你得到E_STRICT。好吧。然後,在這裏閱讀@工作更多Error Control Operators。再次,第一注:

Note: The @-operator works only on expressions. A simple rule of thumb is: if you can take the value of something, you can prepend the @ operator to it. For instance, you can prepend it to variables, function and include calls, constants, and so forth. You cannot prepend it to function or class definitions, or conditional structures such as if and foreach, and so forth.

嘗試此代碼(將棚光):

error_reporting(E_ALL); 

$arr = [1,2,3,4,5,]; 

$a_closure = function(){ 
    return [1,2,3,4,5]; 
}; 

function a(){ 
    return [1,2,3,4,5]; 
} 

function ref_func(&$input){ 
    foreach($input as &$in){ 
     $in++; 
    } 
} 

ref_func($a);   // @ref_func($a); 
ref_func(a());   // @ref_func($a()); 
ref_func($a_closure); // @ref_func($a_closure); 
// Fatals in both 
ref_func([1,2,3,4,5]); // @ref_func([1,2,3,4,5]);