Spl, ArrayObject, ArrayObject::STD_PROP_LIST

Fried Smurf picture Fried Smurf · Jan 30, 2013 · Viewed 13.7k times · Source

I'm trying to understand STD_PROP_LIST constant in the documentation but so far i didn´t understand it, and didn´t found any explanation :( The documentation has the following example:

$a = new ArrayObject(array(), ArrayObject::STD_PROP_LIST);
$a['arr'] = 'array data';                             
$a->prop = 'prop data';                               
$b = new ArrayObject();                                   
$b['arr'] = 'array data';                             
$b->prop = 'prop data';                               

// ArrayObject Object                                     
// (                                                      
//      [prop] => prop data                               
// )                                                      
print_r($a);                                              

// ArrayObject Object                                     
// (                                                      
//      [arr] => array data                               
// )                                                      
print_r($b);

Both prints give me the same exact result:

ArrayObject Object ( [prop] => prop data [storage:ArrayObject:private] => Array ( [arr] =>      array data ) ) 
ArrayObject Object ( [prop] => prop data [storage:ArrayObject:private] => Array ( [arr] => array data ) )

Anyone could help me understanding what is the difference between using this constant or not?

Thanks in advance!

Answer

JayTaph picture JayTaph · May 18, 2013

The ArrayObject and ArrayIterator are 2 classes that are really similar. They actually both share lot of code internally inside the php core. These two classes have a internal array to store the elements you set to those classes.

The STD_PROP_LIST tells us how to read, and ARRAY_AS_PROPS tells us how we to write those elements. First of all,setting elements through the standard array ([]) notation will always work the same way, regardless of these settings.

When setting ARRAY_AS_PROPS flags, it means that when you set properties (through the ->), will not be set on the object like you would expect with regular objects, but will be stored as internal elements. If this flag is NOT set, it will store the property onto the actual array-object or array-iterator, which is what you see in the code output from your example: the "prop => propdata" is not inside the storage:ArrayObject:private, which would have been the case if the ARRAY_AS_PROPS flag would have been set:

$a = new ArrayObject();
$a['arr'] = 'array data';
$a->prop = 'prop data';

$b = new ArrayObject(array(), ArrayObject::ARRAY_AS_PROPS);
$b['arr'] = 'array data';
$b->prop = 'prop data';

print_r($a);
print_r($b);

// Output:
ArrayObject Object
(
    [prop] => prop data
    [storage:ArrayObject:private] => Array
        (
            [arr] => array data
        )
)
ArrayObject Object
(
    [storage:ArrayObject:private] => Array
        (
            [arr] => array data
            [prop] => prop data
        )
)

The STD_PROP_LIST decides on what to return on certain conditions, most notably at var_dump(). Though there will be other cases, i haven't found them myself. If the STD_PROP_LIST is set, it will return the properties that have been set onto your ArrayObject, or ArrayIterator class. If it's NOT set, then var_dump() will return a list of the internal elements that have been stored.

The actual documentation is not 100% correct on STD_PROP_LIST. This flag affects var_dump(), but not foreach(). When using foreach(), it will always iterate the internal elements, and never the actual properties, even when STD_PROP_LIST has been set.

These two flags are not mutually exclusive: you can set both flags, but it wouldn't make much sense doing so: it means that properties are always added as internal elements (ARRAY_AS_PROPS), and we want to return the standard properties through var_dump (STD_PROP_LIST). Since properties cannot have been set, it will always return an empty list in that case.