只能通过引用传递变量

zaf*_*zaf 17 php variables error-handling reference

我有一个明智的想法,即使用自定义错误处理程序导致我陷入了一个兔子洞.

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

function foo(){
    $b=array_pop(array("a","b","c"));
    return $b;
}
print_r(foo());
Run Code Online (Sandbox Code Playgroud)

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

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

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

谁有更好的想法?还有,WTF?

更新:

感谢答案,我已经了解了php如何处理错误.不包括E_STRICT(php 5)的E_ALL混淆并不酷.

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

故事的寓意是使用您自己的错误处理程序来捕获它们并使用错误常量(E_STRICT,E_USER_WARNING,E_USER_ERROR等)来进行过滤.

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

joh*_*nes 18

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());
Run Code Online (Sandbox Code Playgroud)

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


gre*_*ire 9

这是我在将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
Run Code Online (Sandbox Code Playgroud)

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

从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
Run Code Online (Sandbox Code Playgroud)

从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
Run Code Online (Sandbox Code Playgroud)


web*_*ave 5

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

function foo(){
    $b = array_pop($arr = array("a","b","c"));
    return $b;
}
print_r(foo());
Run Code Online (Sandbox Code Playgroud)

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

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


bal*_*loo 1

尝试这个:

function foo(){
    $a = array("a","b","c");
    $b = array_pop($a);
    return $b;
}
Run Code Online (Sandbox Code Playgroud)