Imran Khan
Imran Khan

Reputation: 2401

php SplObjectStorage Detach() not working

I have found an error in PHP SplObjectStorage Detach method. Where it's working fine in removing an object but if the object comes one another it skip the next one.

Example:

$s = new SplObjectStorage();

$o1 = new StdClass;
$o2 = new StdClass;
$o3 = new StdClass;

$o1->attr = '1';
$o2->attr = '2';
$o3->attr = '3';

$s->attach($o1);
$s->attach($o2);
$s->attach($o3);

echo 'Removing Objects...<pre>';
var_dump($s->count());
foreach ($s as $obj) {
   var_dump($obj->attr);
   if($obj->attr == 2 || $obj->attr == 1) {
       echo "Deleting...".$obj->attr;
       $s->detach($obj);
   }
}

echo 'Checking Objects....';
var_dump($s->count());
foreach ($s as $obj) {
   var_dump($obj->attr);
}

and it gives me this result. which shouldn't be, because i want to delete Object (attr == 1) and Object (attr == 2) both. Detach() method only delete first object, then skip the next one and then loop.

Removing Objects...

int 3

string '1' (length=1)

Deleting...1

string '3' (length=1)


Checking Objects....

int 2

string '2' (length=1)

string '3' (length=1)

** Object ($o2->attr = '2') should also be deleted, which is not because skip in the first loop.

Upvotes: 1

Views: 315

Answers (1)

Imran Khan
Imran Khan

Reputation: 2401

I have found a bug in SplObjectStorage Detach() method which are:

Detaching the current entry from the storage prevents SplObjectStorage::next() to operate.

so by preventing the Next object when Detach() execute, the iteration will never reach the second (next) stdClass object. SplObjectStorage::next() obviously relies on the current element to be valid.

To avoid this bug in SplObjectStorage class we needs to call next() before calling detach().

Hope this will help other users not to face this problem and not to waste their time...

Upvotes: 2

Related Questions