$el = array_shift($instance->find(..))
上面的代码以某种方式报告了严格的标准警告,但是不会:
function get_arr(){
return array(1, 2);
}
$el = array_shift(get_arr());
那么,它将何时报告警告呢?
Answers:
考虑以下代码:
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()
方法不是变量,在严格模式下将生成警告。此行为非常不直观,因为该get_arr()
方法返回一个数组值。
要在严格模式下解决此错误,请更改方法的签名,使其不使用引用:
function test_arr($a) {
var_dump($a);
}
由于您无法更改签名,array_shift
因此还可以使用中间变量:
$inter = get_arr();
$el = array_shift($inter);
current
假定数组指针位于第一个元素。在大多数情况下,这可能是一个有效的假设,但需要提防。
array_shift()
,那就是它期望引用被修改:-)
$intermediate
通过使用额外的一对括号来避免该值。$el = array_shift( ( get_arr() ) );
。参见stackoverflow.com/questions/9848295/…–
$instance->find()
返回对变量的引用。
当您尝试将此引用用作函数的参数时,无需先将其存储在变量中即可获取报告。
这有助于防止内存泄漏,并且在以后的PHP版本中可能会成为错误。
如果您的第二个代码块编写如下(请注意&
函数签名中的),则会抛出错误:
function &get_arr(){
return array(1, 2);
}
$el = array_shift(get_arr());
因此,一个快速(但不太好)的修复方法是:
$el = array_shift($tmp = $instance->find(..));
基本上,您首先要对临时变量进行赋值,然后将变量作为参数发送。
array_shift($tmp = $instance->find(..))
将$instance->find(..)
to$tmp
的值赋值,然后将赋值的值传递给array_shift()
-与传递$tmp
自身不同,因此,这比没有赋值的原始情况更好。
错误的原因是内部PHP编程数据结构函数array_shift()[php.net/end]的使用。
该函数将数组作为参数。尽管array_shift()
在手册的原型中指出了“&”号,但该功能的扩展定义后没有任何警告文档,也没有任何明显的解释表明该参数实际上是通过引用传递的。
也许这是/理解/。但是,我不理解,因此我很难检测到错误原因。
重现代码:
function get_arr()
{
return array(1, 2);
}
$array = get_arr();
$el = array_shift($array);
第二个片段也不起作用,这就是原因。
array_shift
是修饰函数,可更改其参数。因此,它希望它的参数是一个引用,并且您不能引用不是变量的内容。参见Rasmus的解释:严格的标准:只能通过引用传递变量
好吧,在类似的明显情况下,您总是可以通过在函数前面使用“ @”来告诉PHP禁止显示消息。
$monthly_index = @array_shift(unpack('H*', date('m/Y')));
用这种方法抑制所有错误可能不是最佳的编程实践之一,但是在某些情况下(如这种情况),它很方便并且可以接受。
结果,我确信您的朋友“系统管理员”会对污染程度较小的文件感到满意error.log
。