Does PHP have autovivification?

2019-04-03 18:43发布

问题:

Searching PHP.net for autovivification gives no results. At the time of writing, Wikipedia claims that only Perl has it. There are no clearly definitive results when searching Google for "php autovivification".

This PHP code runs fine:

$test['a'][4][6]['b'] = "hello world";
var_dump($test);

array
  'a' => 
    array
      4 => 
        array
          'b' => 
            array
              ...

Can anyone provide a canonical answer (preferably with references) that PHP does have this feature, and any details such as the version it was introduced in, quirks, shortcuts etc?

回答1:

Yes, PHP does have autovivification (and has had it for a long time), although it isn't referenced by that terminology. PHP.net states:

An existing array can be modified by explicitly setting values in it.

This is done by assigning values to the array, specifying the key in brackets. The key can also be omitted, resulting in an empty pair of brackets ([]).

$arr[key] = value;
$arr[] = value;
// key may be an integer or string
// value may be any value of any type

If $arr doesn't exist yet, it will be created, so this is also an alternative way to create an array.

However, the documentation states that if you try to access the value of an unset array (or key), it will return an error:

Attempting to access an array key which has not been defined is the same as accessing any other undefined variable: an E_NOTICE-level error message will be issued, and the result will be NULL.

I have tracked down my old PHP3 manual, which states this:

You can also create an array by simply adding values to the array.

$a[] = "hello";


回答2:

Well not 100% if PHP supports autovivification but the syntax you posts works for the most part.

// Works as you have assigned a value of 'hello'
$a['a'][4][6]['b'] = "hello";
var_dump($a);
echo print_r($a,true);

// works as you have assigned a value of 'world'
$b[][][][] = "world";
var_dump($b);
echo print_r($b,true);

// ERROR: Cannot use [] for reading
$c[];
var_dump($c);
echo print_r($c,true);

Cannot use [] for reading: Related Link



回答3:

in perl, items will autovivify upon inspection, assignment is not necessary. The path of items necessary to get to the innermost requested key will be created upon inspection. Note that the {d => undef} is entry is not actually created but is implied.

   use strict;
   use warnings;
   use Data::Dumper;

   my %a;       # as is empty, equivalent to \%a is {};
   print Dumper %a;
   $a{b}{c}{d}; # \%a is now { b => { c => {}}}
                # returns an undef value.
   print Dumper \%a;

output:

$VAR1 = {};
$VAR1 = {
          'b' => {
                   'c' => {}
                 }
        };

perl array example:

use strict;
use warnings;
use Data::Dumper;

my (@b,@c);          # @b=(), @c=()
print Dumper \@b;
$b[3];               # @b=() aka unchanged.
print Dumper \@b;
$b[3][2][1];         # @b=(undef,undef,undef,[undef,undef,[]])
print Dumper \@b;
print Dumper \@c;
$c[3]=1  ;           # @c=(undef,undef,undef,1)
print Dumper \@c;

Output:

Useless use of array element in void context at -e line 7.
Useless use of array element in void context at -e line 9.
$VAR1 = [];
$VAR1 = [];
$VAR1 = [
          undef,
          undef,
          undef,
          [
            undef,
            undef,
            []
          ]
        ];
$VAR1 = [];
$VAR1 = [
          undef,
          undef,
          undef,
          1
        ];