9

更新:我提出这个问题的初衷是确定 PHP 是否真的有这个功能。这在答案对标量问题的关注中丢失了。请改为查看这个新问题:“PHP 是否具有自动生存功能?” 这个问题留在这里供参考。

根据 Wikipedia,PHP 没有 autovivification,但此代码有效:

$test['a']['b'] = 1;
$test['a']['c'] = 1;
$test['b']['b'] = 1;
$test['b']['c'] = 1;

var_dump($test);

输出:

array
  'a' => 
    array
      'b' => int 1
      'c' => int 1
  'b' => 
    array
      'b' => int 1
      'c' => int 1

我发现这段代码也有效:

$test['a'][4] = 1;
$test['b'][4]['f'] = 3;

但是添加此行会导致警告(“警告:不能将标量值用作数组”)

$test['a'][4]['f'] = 3;

这里发生了什么?为什么在索引后添加关联元素时会失败?这是“真正的”类似 Perl 的自动生存,还是它的某种变体,还是其他什么?

编辑:哦,我现在看到标量错误,哎呀!这些按预期工作:

$test['a'][4]['a'] = 1;
$test['a'][4]['b'] = 2;
$test['a'][5]['c'] = 3;
$test['a'][8]['d'] = 4;

那么,php 确实有 autovivification 吗?在 Google 中搜索“php autovivification”并没有找到规范的答案或示例。

4

3 回答 3

7

来自关于方括号语法的PHP 手册:

$arr[] = value;

如果$arr尚不存在,则会创建它,因此这也是创建数组的另一种方式

用你的例子:

$test['a'][4] = 1;

既然$test$test['a']目前不存在;它们都被创建为数组。

$test['b'][4]['f'] = 3;

$test['b']并且$test['b'][4]目前不存在;它们都被创建为数组。

$test['a'][4]['f'] = 3;

$test['a'][4] 确实存在,但它是一个整数 ( 1)。这是不能用作数组的“标量值”。您不能[]对数值使用方括号语法;它不会将现有值转换为数组。

于 2011-05-11T09:59:10.907 回答
3

根据结果​​,PHP 有 autovivification。错误来自它的工作方式。

当你说:$a[1][2] = 55 时,PHP 想要将 55 插入到 $a[1] 中,因为 [2]=>55。由于 $a[1] 不存在,PHP 会自动创建一个空节点cca。$a[1] = 数组()。但是当节点已经存在时,PHP不会创建$a[1],只是执行[2]=>55,如果$a[1]不是array-like (array, object)的话,这是一个错误。

我见过的最后一种语言是 MUMPS,其中节点可能具有值和子节点。还有一个名为 $DATA() 的函数,它告诉节点是否有任何子节点 (10)、值 (1) 或两者都有 (11),或者它不存在 (0)。我认为,这是对关联数组的正确处理。

(无论如何,我喜欢 PHP 的这种行为。)

于 2011-05-11T10:08:01.747 回答
1

和:

$test['b'][4]['f'] = 3;

你没有添加一个元素

$test['a'][4]

因为它没有初始化为数组。

如果你写:

$test['a'][4] = array(1);

然后它会工作。

和:

$test['a']['b'] = 1;
$test['a']['c'] = 1;
$test['b']['b'] = 1;
$test['b']['c'] = 1;

您正在隐式初始化$test['a']$test['b']作为数组。但是$test['a']['b'](等等)作为int

于 2011-05-11T09:58:16.253 回答