2017-07-06 180 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]);