只有变量可以通过引用传递

2022-08-30 20:52:32

我有一个好主意,使用一个自定义的错误处理程序,把我带到了一个兔子洞。

以下代码给出(带或不带自定义错误处理程序):致命错误:只能通过引用传递变量

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

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

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

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

有人有更好的想法吗?另外,WTF?

更新

多亏了这些答案,我学到了一些关于php如何处理错误的知识。E_ALL不包括E_STRICT(php 5)的混淆并不酷。

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

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

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


答案 1

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());

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


答案 2

以下是我在php-cli中尝试将error_reporting设置为E_ALL |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

如您所见,这里只是严格的标准。您可以轻松地让自定义错误处理程序忽略它们(基于您获得的值:例如,此处为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

从 php 5.4 开始,确实包括:E_ALLE_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

推荐