php 只能通过引用传递变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2967597/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 08:16:32  来源:igfitidea点击:

Only variables can be passed by reference

phperror-handlingvariablesreference

提问by zaf

I had the bright idea of using a custom error handler which led me down a rabbit hole.

我有一个使用自定义错误处理程序的好主意,这让我陷入了困境。

Following code gives (with and without custom error handler): Fatal error: Only variables can be passed by reference

以下代码给出(有和没有自定义错误处理程序):致命错误:只有变量可以通过引用传递

function foo(){
    $b=array_pop(array("a","b","c"));
    return $b;
}
print_r(foo());

Following code gives (only with a custom error handler): (2048) Only variables should be passed by reference

以下代码给出(仅使用自定义错误处理程序):(2048)仅应通过引用传递变量

function foo(){
    $a=explode( '/' , 'a/b/c');
    $c=array_pop(array_slice($a,-2,1));
    return $c;
}
print_r(foo());

The second one worries me since I have a lot of 'compact' code. So, I either ditch the bright idea of using a custom error handler (to improve my logging module) or expand all my code.

第二个让我担心,因为我有很多“紧凑”的代码。因此,我要么放弃使用自定义错误处理程序(以改进我的日志记录模块)的好主意,要么扩展我的所有代码。

Anyone with better ideas? Also, WTF?

有人有更好的想法吗?还有,WTF?

UPDATE:

更新

Thanks to the answers I've learnt something about how php does error handling. The confusion of E_ALL not including E_STRICT (php 5) is not cool.

多亏了这些答案,我对 php 如何处理错误有了一些了解。不包括 E_STRICT (php 5) 的 E_ALL 的混乱并不酷。

On top of all this, creating your own custom error handler enables E_STRICT by default and thats where problems start.

最重要的是,创建自己的自定义错误处理程序默认启用 E_STRICT,这就是问题开始的地方。

The moral of the story is to use your own error handler to catch them ALL and use the error constants (E_STRICT, E_USER_WARNING, E_USER_ERROR, etc.) to do your filtering.

这个故事的寓意是使用您自己的错误处理程序将它们全部捕获并使用错误常量(E_STRICT、E_USER_WARNING、E_USER_ERROR 等)进行过滤。

As for the 'memory corruption issue' with variable references and certain functions, what can I say? Doubly uncool. I'll (which doesn't mean you should) ignore E_STRICT in my error handler and life goes on.

至于变量引用和某些函数的“内存损坏问题”,我能说什么?双重不爽。我会(这并不意味着你应该)在我的错误处理程序中忽略 E_STRICT 并且生活继续。

回答by johannes

array_pop() tries to change that value which is passed as parameter. Now in your second example this is the return value from array_slice(). In engine terms this is a "temporary value" and such a value can't be passed by references. what you need is a temporary variable:

array_pop() 尝试更改作为参数传递的值。现在在您的第二个示例中,这是 array_slice() 的返回值。在引擎术语中,这是一个“临时值”,并且不能通过引用传递这样的值。你需要的是一个临时变量:

function foo(){
    $a=explode( '/' , 'a/b/c');
    $b=array_slice($a,-2,1);
    $c=array_pop($b);
    return $c;
}
print_r(foo());

Then a reference to $b can be passed to array_pop(). See http://php.net/referencesfor more details on references.

然后可以将 $b 的引用传递给 array_pop()。有关参考资料的更多详细信息,请参阅http://php.net/references

回答by greg0ire

Here is what I get when trying your second php code snippet in php-cli after setting error_reporting to E_ALL | E_STRICT

这是我在将 error_reporting 设置为 E_ALL 后在 php-cli 中尝试第二个 php 代码片段时得到的结果| E_STRICT

    gparis@techosaure:~/workspace/universcine.com$ php -a
Interactive shell

php > function foo(){
php {     $a=explode( '/' , 'a/b/c');
php {     $c=array_pop(array_slice($a,-2,1));
php {     return $c;
php { }
php > print_r(foo());
PHP Strict standards:  Only variables should be passed by reference in php shell code on line 3
PHP Stack trace:
PHP   1. {main}() php shell code:0
PHP   2. foo() php shell code:1

As you can see, it's only strict standards here. And you can easily let your custom error handler ignore them (based on the value you get : 2048 for instance, here).

如您所见,这里只是严格的标准。并且您可以轻松地让您的自定义错误处理程序忽略它们(基于您获得的值:例如,此处为 2048)。

As of php 5.3, E_ALL does not include E_STRICT, look at this :

从 php 5.3 开始,E_ALL 不包括 E_STRICT,看看这个:

php > foreach(array("E_ALL", "E_DEPRECATED", "E_STRICT", "E_NOTICE", "E_PARSE", "E_WARNING") as $const) echo $const . "  :\t" . constant($const) ."\t". decbin(constant($const)). "\n";
E_ALL  :        30719   111011111111111
E_DEPRECATED  : 8192     10000000000000
E_STRICT  :     2048       100000000000
E_NOTICE  :     8                  1000
E_PARSE  :      4                   100
E_WARNING  :    2                    10

As of php 5.4, E_ALLdoes include E_STRICT:

从 php 5.4 开始,E_ALL确实包括E_STRICT

E_ALL  :            32767   111111111111111
E_DEPRECATED  :     8192     10000000000000
E_STRICT  :         2048       100000000000
E_NOTICE  :         8                  1000
E_PARSE  :          4                   100
E_WARNING  :        2                    10

回答by webbiedave

It's a memory corruption issue (according to PHP dev team). Just throw in an assignment:

这是一个内存损坏问题(根据 PHP 开发团队的说法)。只需抛出一个任务:

function foo(){
    $b = array_pop($arr = array("a","b","c"));
    return $b;
}
print_r(foo());

:

function foo(){
    $a = explode( '/' , 'a/b/c');
    $c = array_pop($arr = array_slice($a,-2,1));
    return $c;
}
print_r(foo());

The second produces an E_STRICT. You can handle that differently in your error handler if you wish (if you don't want to change those functions).

第二个产生 E_STRICT。如果您愿意(如果您不想更改这些函数),您可以在错误处理程序中以不同的方式处理它。

回答by popeyems

I think that now (since php 5) it should be:

我认为现在(从 php 5 开始)应该是:

function &foo(){ //NOTICE THE &
    $b=array_pop(array("a","b","c"));
    return $b;
}
print_r(foo());

and

function &foo(){ //NOTICE THE &
    $a=explode( '/' , 'a/b/c');
    $c=array_pop(array_slice($a, $b = -2, $c = 1)); //NOW NO DIRECT VALUES ARE PASSED IT MUST BE VARIABLES
    return $c;
}
print_r(foo());

but i'm just a begginer :)

但我只是一个初学者:)

回答by Joseph

array_pop()changes that value passed to it which is where the error is coming from. A function cannot be changed. In other words, you need to assign the array to a variable first (ref: manual), and then run array_pop().

array_pop()更改传递给它的值,这是错误的来源。无法更改功能。换句话说,您需要先将数组分配给一个变量(参考:手册),然后运行array_pop()

The code you need is this:

你需要的代码是这样的:

function foo(){
    $a = array("a","b","c");
    $b = array_pop($a);
    return $b;
}


Edit:Both functions you mentioned have the same problem. Assign the array to a variable and pass the variable to array_pop().

编辑:您提到的两个功能都有相同的问题。将数组分配给一个变量并将该变量传递给array_pop().

回答by baloo

Try this:

尝试这个:

function foo(){
    $a = array("a","b","c");
    $b = array_pop($a);
    return $b;
}

回答by agm1984

I just got this error chaining methods.

我刚刚得到这个错误链接方法。

doSomething()->andThis()

I had:

我有:

doSomething()-andThis() // missing `>` character

My scenario was a little more complex, but it stemmed from the accidental subtractionoperation.

我的场景有点复杂,但它源于意外subtraction操作。