否"未定义的偏移"如果array为NULL

时间:2014-03-17 14:11:19

标签: php

我不确定这是一个错误,所以如果你试图访问一个没有定义为NULL的数组的密钥,那么有人可以告诉为什么php不会显示通知吗?文档说

Converting NULL to an array results in an empty array.

因此,访问未定义的密钥必须生成通知。

<?php

$a = NULL;
echo $a['1'];

$a = array();
echo $a['1'];
?>

打印出来

Notice: Undefined offset: 1 in /var/www/shared/1.php on line 14

感谢您的帮助。


编辑:我冒昧地在问题

中添加另一个示例脚本
<?php
$a = NULL;
var_dump('line '.__LINE__, $a['1']);

$a = array();
var_dump('line '.__LINE__, $a['1']);

打印

string(6) "line 3"
NULL

Notice: Undefined offset: 1 in [...]/test.php on line 6
string(6) "line 6"
NULL

2 个答案:

答案 0 :(得分:3)

当您将变量取消引用为数组(用于读取)时,虚拟机将在内部调用zend_fetch_dimension_address_read,然后根据您尝试的变量类型将正确的值加载到结果变量中取消引用。

如果是null(和int / float / bool),它将选择this branch

case IS_NULL:
  result->var.ptr = &EG(uninitialized_zval);
  PZVAL_LOCK(&EG(uninitialized_zval));
  return;

其中EG(uninitialized_zval)基本上是null本身;发生这种情况时不会发出任何通知。正如Amal指出的那样,这种行为有bug report,但近一年来没有做过多少。

  

文档说“将NULL转换为数组会产生一个空数组。”

数组解除引用不会将某些内容转换为数组(除非您使用[]或在写入上下文中使用它)。手册所说的转换很可能是阵列演员:

var_dump((array)null);
// array(0) { }

更新

在深入挖掘系统之后,我发现这(部分)使得以下构造工作:

$list = ['foo', 'bar', 'baz'];
while (list($key, $value) = each($list)) {
    echo "$key: $value\n";
}

当到达数组的末尾时,each()返回false,因此在false[0]表达式本身产生{{}之前评估内部false[1]list() {1}}。

答案 1 :(得分:1)

这似乎实际上报告为bug。这是我在评论部分找到的内容(调整后的描述以匹配您的变量名称):

您的代码:

$a = NULL;
echo $a['1'];

$a = array();
echo $a['1'];

此处,变量$a最初声明为NULL类型的变量。 $a最初声明为NULL

在第一个echo语句中,有效地忽略了在1中引用$a索引的尝试:变量不是一个开头的数组。

然后将

$a强制转换为数组。 ($a = array();

在第二个echo语句中,$a是一个空数组,PHP可以枚举并最终确定索引1 存在。

因此第一个echo会产生NULL输出,而第二个会导致PHP发出E_NOTICE。