User Contributed Notes 10 notes

Note some inconsistent/surprising behavior in SplObjectStorage to preserve backwards compatibility. You can't properly use foreach with key/value syntax.

<?php$spl = new SplObjectStorage ();$keyForA = new StdClass();$keyForB = new StdClass();$spl[$keyForA] = 'value a';$spl[$keyForB] = 'value b';foreach ($spl as $key => $value){// $key is NOT an object, $value is! // Must use standard array access to get strings.echo $spl[$value] . "\n"; // prints "value a", then "value b"}// it may be clearer to use this form of foreach:foreach ($spl as $key){// $key is an object. // Use standard array access to get values.echo $spl[$key] . "\n"; // prints "value a", then "value b"}?>

<?php/** * For simple use cases (where you want to keep objects in a map) * I would suggest to stick to an plain old array. Just use the object * hash as array key. */$entity1 = new stdClass();$entity2 = new stdClass();$entities = [];$entities[spl_object_hash($entity1)] = $entity1;$entities[spl_object_hash($entity2)] = $entity2;

// object hashes are hard to distinguish so you could run a hash function// on them for better readability.$entities[md5(spl_object_hash($entity1))] = $entity1;$entities[md5(spl_object_hash($entity2))] = $entity2;

Keep in mind that foreach() will copy your array before iterating, SplObjectStorage does not. If you have a sub call within an iteration that also calls foreach() on the object storage again, the iterator position collides!

I rewrote some scripts and changed object storage with arrays to SplObjectStorage. At some point I needed support of array_rand() but I did not find a function to return a random attached object of an SplObjectStorage object.

#1: A reference to the object itself is stored (not just a hash to compare against the object) and it must be removed before the object is destroyed and the destructor is executed.

#2: SplObjectStorage::rewind() MUST be called to initiate the iterator and before SplObjectStorage::current() will return an object (and I think the only way to retrieve an object?) rather than automatically starting at the first element as I expected it to, like an array for example. This assumption is based on SplObjectStorage::current() returning NULL until SplObjectStorage::rewind() is called once the objects are contained. As a note, always use REWIND before iterating through or fetching objects.