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”))//是的,这很傻,但它是有效的:)谢谢你的回答。我没有时间尝试,但你是说添加一个“&”可以让它工作吗?它有什么作用?我明天再查。