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

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

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

那么它什么时候会报告警告呢?

4

6 回答 6

93

考虑以下代码:

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);
于 2010-03-01T09:14:24.443 回答
7

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

当您尝试将此引用用作函数的参数时,您会得到报告,而无需先将其存储在变量中。

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

&如果你的第二个代码块这样写(注意函数签名中的),它会抛出一个错误:

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

所以一个快速(但不是很好)的解决方法是:

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

基本上,您首先对临时变量进行赋值,然后将该变量作为参数发送。

于 2010-03-01T09:00:28.453 回答
6

错误的原因是使用了内部 PHP 编程数据结构函数,array_shift() [php.net/end]。

该函数将数组作为参数。尽管在手册中的原型中标出了与号array_shift(),但在该函数的扩展定义中没有任何警示文档,也没有任何明显的解释表明该参数实际上是通过引用传递的。

也许这是/理解/。然而,我不明白,所以我很难发现错误的原因。

重现代码:

function get_arr()
{
    return array(1, 2);
}
$array = get_arr();
$el = array_shift($array);
于 2014-11-25T12:16:43.760 回答
3

第二个片段也不起作用,这就是原因。

array_shift是一个修饰函数,它改变它的参数。因此它期望它的参数是一个引用,并且你不能引用不是变量的东西。请在此处查看 Rasmus 的解释:严格标准:仅应通过引用传递变量

于 2010-03-01T09:24:10.083 回答
3

这段代码:

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

需要改成:

$date_time = date('m/Y');
$unpack = unpack('H*', $date_time);
array_shift($unpack);
于 2016-03-07T21:36:53.517 回答
0

好吧,在这种明显的情况下,您总是可以通过在函数前面使用“@”来告诉 PHP 禁止消息。

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

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

因此,我相信您的朋友“系统管理员”会对污染较少的error.log.

于 2016-12-08T22:09:04.607 回答