Monday, April 23, 2012

Does PHP have autovivification?


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?


Source: Tips4all

3 comments:

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

    ReplyDelete
  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

    ReplyDelete
  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
    ];

    ReplyDelete