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?
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";
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
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
];