10

In PHP 5.4 I have an instance of SplObjectStorage where I associate objects with some extra metadata. I need to then iterate through the instance of SplObjectStorage and retrieve the object associated with the current key. I attempted to use SplObjectStorage::key but that did not work (but may work in PHP 5.5).

Here is a simplified version of what I am attempting to do:

$storage = new SplObjectStorage;
$foo = (object)['foo' => 'bar'];
$storage->attach($foo, ['room' => 'bar'];

foreach ($storage as $value) {
    print_r($value->key());
}

All I really need is some way to retrieve the actual object that is associated with the key. It is not even possible to manually create a separate indexed array with the numeric index and the object SplObjectStorage points to, as far as I can tell.

hakre
  • 193,403
  • 52
  • 435
  • 836
Phillip Whelan
  • 1,697
  • 2
  • 17
  • 28

2 Answers2

10

Do it:

$storage = new SplObjectStorage;
$foo = (object)['foo' => 'bar'];
$storage->attach($foo, ['room' => 'bar']);

foreach ($storage as $value) {
    $obj = $storage->current(); // current object
    $assoc_key  = $storage->getInfo(); // return, if exists, associated with cur. obj. data; else NULL

    var_dump($obj);
    var_dump($assoc_key);
}

See more SplObjectStorage::current and SplObjectStorage::getInfo.

voodoo417
  • 11,861
  • 3
  • 36
  • 40
  • 1
    you sure?i am checked : `object(stdClass)#2 (1) { ["foo"]=> string(3) "bar" } array(1) { ["room"]=> string(3) "bar" } ` – voodoo417 Jan 27 '14 at 20:32
  • 2
    try add another object (`foo1`) withoud associated data - $assoc_key wiil be `NULL` – voodoo417 Jan 27 '14 at 20:40
  • 4
    Apparently $storage->current() returns the object that is used as the key and $storage->getInfo() returns the data associated to it. This was not obvious to me since Iterator::current() usually returns the data associated with the key and vice-versa. – Phillip Whelan Jan 28 '14 at 23:19
1

When SplObjectStorage was created, Iterators could not return object-valued keys (which was fixed later, but SplObjectStorage was not changed for BC reasons). So using foreach to iterate over SplObjectStorage returns the keys as values, and you have to retrieve the values yourself like this (play on 3v4l.org):

<?php
$spl = new SplObjectStorage ();

$keyForA = (object) ['key' => 'A'];
$keyForB = (object) ['key' => 'B'];

$spl[$keyForA] = 'value a';
$spl[$keyForB] = 'value b';

foreach ($spl as $i => $key) {
  $value = $spl[$key];

  print "Index: $i\n";
  print "Key: " . var_export($key, TRUE) . "\n";;
  print "Value: " . var_export($value, TRUE) . "\n";;
  print "\n";
}
?>
geek-merlin
  • 1,720
  • 17
  • 13