简体   繁体   English

错误消息“严格的标准:只应通过引用传递变量”

[英]Error message "Strict standards: Only variables should be passed by reference"

$el = array_shift($instance->find(..))

The above code somehow reports the strict standards warning, but this will not:上面的代码以某种方式报告了严格的标准警告,但这不会:

function get_arr(){
    return array(1, 2);
}
$el = array_shift(get_arr());

So when will it report the warning anyway?那么它什么时候会报告警告呢?

Consider the following code:考虑以下代码:

error_reporting(E_STRICT);
class test {
    function test_arr(&$a) {
        var_dump($a);
    }
    function get_arr() {
        return array(1, 2);
    }
}

$t = new test;
$t->test_arr($t->get_arr());

This will generate the following output:这将生成以下输出:

Strict Standards: Only variables should be passed by reference in `test.php` on line 14
array(2) {
  [0]=>
  int(1)
  [1]=>
  int(2)
}

The reason?原因? The test::get_arr() method is not a variable and under strict mode this will generate a warning. test::get_arr()方法不是变量,在严格模式下会产生警告。 This behavior is extremely non-intuitive as the get_arr() method returns an array value.这种行为非常不直观,因为get_arr()方法返回一个数组值。

To get around this error in strict mode, either change the signature of the method so it doesn't use a reference:要在严格模式下解决此错误,请更改方法的签名,使其不使用引用:

function test_arr($a) {
    var_dump($a);
}

Since you can't change the signature of array_shift you can also use an intermediate variable:由于您无法更改array_shift的签名,您还可以使用中间变量:

$inter = get_arr();
$el = array_shift($inter);

$instance->find() returns a reference to a variable. $instance->find()返回对变量的引用。

You get the report when you are trying to use this reference as an argument to a function, without storing it in a variable first.当您尝试将此引用用作函数的参数时,您会得到报告,而无需先将其存储在变量中。

This helps preventing memory leaks and will probably become an error in the next PHP versions.这有助于防止内存泄漏,并且可能会在下一个 PHP 版本中成为错误。

Your second code block would throw an error if it wrote like (note the & in the function signature):如果你的第二个代码块像这样写(注意函数签名中的& ,它会抛出一个错误:

function &get_arr(){
    return array(1, 2);
}
$el = array_shift(get_arr());

So a quick (and not so nice) fix would be:所以一个快速(而不是那么好)的解决方法是:

$el = array_shift($tmp = $instance->find(..));

Basically, you do an assignment to a temporary variable first and send the variable as an argument.基本上,您首先对临时变量进行赋值,然后将该变量作为参数发送。

The cause of the error is the use of the internal PHP programming data structures function, array_shift() [php.net/end].错误的原因是使用了内部 PHP 编程数据结构函数,array_shift() [php.net/end]。

The function takes an array as a parameter.该函数接受一个数组作为参数。 Although an ampersand is indicated in the prototype of array_shift() in the manual", there isn't any cautionary documentation following in the extended definition of that function, nor is there any apparent explanation that the parameter is in fact passed by reference.尽管在手册中array_shift()的原型中指示了一个&符号”,但在该函数的扩展定义中没有任何警告文档,也没有任何明显的解释表明该参数实际上是通过引用传递的。

Perhaps this is /understood/.也许这是/理解/。 I did not understand, however, so it was difficult for me to detect the cause of the error.然而,我不明白,所以我很难发现错误的原因。

Reproduce code:重现代码:

function get_arr()
{
    return array(1, 2);
}
$array = get_arr();
$el = array_shift($array);

The second snippet doesn't work either and that's why.第二个片段也不起作用,这就是原因。

array_shift is a modifier function, that changes its argument. array_shift是一个修饰函数,它改变了它的参数。 Therefore it expects its parameter to be a reference, and you cannot reference something that is not a variable.因此它期望它的参数是一个引用,你不能引用不是变量的东西。 See Rasmus' explanations here: Strict standards: Only variables should be passed by reference在此处查看 Rasmus 的解释:严格标准:仅变量应通过引用传递

This code:这段代码:

$monthly_index = array_shift(unpack('H*', date('m/Y')));

Need to be changed into:需要改成:

$date_time = date('m/Y');
$unpack = unpack('H*', $date_time);
array_shift($unpack);

Well, in obvious cases like that, you can always tell PHP to suppress messages by using "@" in front of the function.好吧,在这种明显的情况下,您总是可以通过在函数前使用“@”来告诉 PHP 抑制消息。

$monthly_index = @array_shift(unpack('H*', date('m/Y')));

It may not be one of the best programming practices to suppress all errors this way, but in certain cases (like this one) it comes handy and is acceptable.以这种方式抑制所有错误可能不是最佳编程实践之一,但在某些情况下(例如这种情况)它很方便并且是可以接受的。

As result, I am sure your friend 'system administrator' will be pleased with a less polluted error.log .因此,我相信您的朋友“系统管理员”会对污染较少的error.log感到满意。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM