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

Php 只有变量可以通过引用传递,php,error-handling,variables,reference,Php,Error Handling,Variables,Reference,我有一个聪明的想法,就是使用一个定制的错误处理程序,它把我引入了一个兔子洞 以下代码给出了(有和没有自定义错误处理程序):致命错误:只有变量可以通过引用传递 function foo(){ $b=array_pop(array("a","b","c")); return $b; } print_r(foo()); function foo(){ $a=explode( '/' , 'a/b/c'); $c=array_pop(array_slice($a,-2,

我有一个聪明的想法,就是使用一个定制的错误处理程序,它把我引入了一个兔子洞

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

function foo(){
    $b=array_pop(array("a","b","c"));
    return $b;
}
print_r(foo());
function foo(){
    $a=explode( '/' , 'a/b/c');
    $c=array_pop(array_slice($a,-2,1));
    return $c;
}
print_r(foo());
下面的代码给出(仅使用自定义错误处理程序)():(2048)仅应通过引用传递变量

function foo(){
    $b=array_pop(array("a","b","c"));
    return $b;
}
print_r(foo());
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(PHP5)的混淆并不酷

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

这个故事的寓意是使用您自己的错误处理程序捕获所有错误,并使用错误常量(E_STRICT、E_USER_WARNING、E_USER_error等)进行过滤

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

试试这个:

function foo(){
    $a = array("a","b","c");
    $b = array_pop($a);
    return $b;
}
数组_pop()尝试更改作为参数传递的值。现在在第二个示例中,这是数组_slice()的返回值。在引擎术语中,这是一个“临时值”,这样的值不能通过引用传递。您需要的是一个临时变量:

function foo(){
    $a=explode( '/' , 'a/b/c');
    $b=array_slice($a,-2,1);
    $c=array_pop($b);
    return $c;
}
print_r(foo());
然后可以将对$b的引用传递给数组_pop()。有关引用的更多详细信息,请参阅。

array\u pop()
更改传递给它的值,而该值正是错误的来源。函数不能更改。换句话说,您需要首先将数组分配给一个变量(ref:),然后运行
array\u pop()

您需要的代码如下:

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


编辑:您提到的两个函数都有相同的问题。将数组分配给一个变量,并将该变量传递给
array\u pop()

这是一个内存损坏问题(根据PHP开发团队的说法)。只需加入一项作业:

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


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

以下是我在php cli中将错误报告设置为E|ALL | E|u STRICT后尝试第二个php代码片段时得到的结果

    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
从PHP5.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
我认为现在(从php 5开始)应该是:

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


但我只是一个乞丐:)

同样的问题。

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

doSomething()->andThis()
我有:

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

我的情况稍微复杂一点,但它源于意外的
减法操作。

我在某处看到了这个把戏。这适用于所有函数还是某些函数?您可以在任何函数中抛出赋值。但不是在语言结构中,例如
empty
。这严重妨碍了我的功夫。参数列表中的赋值是未定义的行为。使用数组_pop($arr=array(“a”、“b”、“c”));不清楚首先会发生什么-$arr=array(“a”、“b”、“c”)或array_pop($arr)或array_pop(array(“a”、“b”、“c”));并且可以在所有版本之间进行更改。@johannes:你为什么这么说?不,不是这样,我编辑我的帖子是为了添加一个解释性的代码片段。看到E_ALL中缺少的1了吗?如果你加上E_STRICT,你会得到111111111!意味着中大奖!在PHP5.3中,E_ALL包含E_stricno,但在PHP6中它将包含E_stricno。请看这篇文章:事实上,E_STRICT包含在PHP 5.4的E_ALL中(如链接问题中所述)-请看PHP手册:-但是,仍然错误地报告它仅包含在PHP 6中。@w3d:你是对的,我更新了我的答案,如果你看到错误,请自行修改。$b=当前(数组反向(数组(“a”,“b”,“c”))//是的,这很傻,但它是有效的:)谢谢你的回答。我没有时间尝试,但你是说添加一个“&”可以让它工作吗?它有什么作用?我明天再查。