严格的标准:只有variables应该通过引用传递

$el = array_shift($instance->find(..)) 

上面的代码以某种方式报告严格的标准警告,但是这不会:

 function get_arr(){ return array(1,2); } $el = array_shift(get_arr()); 

那么它何时会报告警告呢?

考虑下面的代码:

 error_reporting(E_STRICT); class test { function test_arr(&$a) { var_dump($a); } function get_arr() { return array(1,2); } } $t= new test; $t->test_arr($t->get_arr()); 

这将生成以下输出:

 Strict Standards: Only variables should be passed by reference in test.php on line 14 array(2) { [0]=> int(1) [1]=> int(2) } 

原因? test::get_arr()方法不是一个variables,在严格模式下会产生警告。 这种行为是非常不直观的,因为get_arr()方法返回一个数组值。

要在严格模式下解决此错误,请更改该方法的签名,使其不使用引用:

 function test_arr($a) { var_dump($a); } 

既然你不能改变array_shift的签名,你也可以使用一个中间variables:

 $inter= get_arr(); $el= array_shift($inter); 

$instance->find()返回对variables的引用。

当您试图将此引用用作函数的参数时,您会得到报告,而不是首先将其存储在variables中。

这有助于防止内存泄漏,并可能会在下一个PHP版本中出现错误。

你的第二个代码会抛出错误,如果它写(像&function签名):

 function &get_arr(){ return array(1,2); } $el = array_shift(get_arr()); 

所以一个快速(而不是很好)的修复将是:

 $el = array_shift($tmp = $instance->find(..)); 

基本上你首先做一个临时variables赋值,然后把variables作为参数发送。

错误的原因是使用内部PHP编程数据结构函数array_shift()[php.net/end]。 该函数将一个数组作为参数。 虽然“手册”中的“array_shift()”的原型中显示了&符号,但在该函数的扩展定义中没有提供警告文档,也没有任何明显的解释说明参数实际上是通过引用传递的。这是/理解/,但我不明白,所以我很难找出错误的原因。

重现代码:

 function get_arr() { return array(1,2); } $array = get_arr(); $el = array_shift($array); 

第二个片段也不起作用,这就是为什么。 array_shift是一个修饰符函数,它改变了它的参数,因此它期望它的参数是一个引用,并且你不能引用那些不是variables的东西。 请参阅Rasmus的解释: http : //bugs.php.net/bug.php?id = 48937

此代码:

 $monthly_index = array_shift(unpack('H*', date('m/Y'))); 

编辑为:

 $date_time = date('m/Y'); $unpack = unpack('H*', $date_time); array_shift($unpack); 

那么,在这种明显的情况下,你总是可以通过在函数前面使用“@”来告诉PHP抑制消息。

$monthly_index = @array_shift(unpack('H*', date('m/Y')));

它可能不是用这种方式压制所有错误的最好的编程实践之一,但是在某些情况下(比如这个),它来得方便并且是可以接受的。

因此,我相信你的朋友SysAdmin将会对污染较less的“error.log”感到满意。 ;)