如果array为NULL,则不为"Undefined offset"

ila*_*pov 5 php

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

Converting NULL to an array results in an empty array.
Run Code Online (Sandbox Code Playgroud)

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

<?php

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

$a = array();
echo $a['1'];
?>
Run Code Online (Sandbox Code Playgroud)

打印出来

Notice: Undefined offset: 1 in /var/www/shared/1.php on line 14
Run Code Online (Sandbox Code Playgroud)

谢谢您的帮助.


编辑:我冒昧地在问题中添加另一个示例脚本

<?php
$a = NULL;
var_dump('line '.__LINE__, $a['1']);

$a = array();
var_dump('line '.__LINE__, $a['1']);
Run Code Online (Sandbox Code Playgroud)

打印

string(6) "line 3"
NULL

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

Ja͢*_*͢ck 3

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

在 (和 int / float / bool) 的情况下null,它将选择这个分支

case IS_NULL:
  result->var.ptr = &EG(uninitialized_zval);
  PZVAL_LOCK(&EG(uninitialized_zval));
  return;
Run Code Online (Sandbox Code Playgroud)

基本上EG(uninitialized_zval)就是它null本身;发生这种情况时不会发出任何通知。正如 Amal 指出的那样,有一个针对此行为的错误报告,但近一年来对此并没有采取太多措施。

文档说“将 NULL 转换为数组会导致空数组。”

数组取消引用不会将某些内容转换为数组(除非您使用[]它或在写入上下文中使用它)。手册中提到的转换很可能是数组转换:

var_dump((array)null);
// array(0) { }
Run Code Online (Sandbox Code Playgroud)

更新

在深入研究系统之后,我发现这(部分)使得以下构造起作用:

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

当到达数组末尾时,会在内部each()返回falsefalse[0],并在表达式本身产生false[1]之前进行评估。list()false