SplObjectStorage

In this post I will look at SplObjectStorage: a container that allows to store objects uniquly without the need to compare them one by one.

Adding objects

So, what can the SplObjectStorage do for you? Let’s see how it behaves when we start to use it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
 
/**
 *  Test class that we will store in the
 *  SplObjectStorage object.
 */
class StorageTest {
    private $title;
 
    public function __construct( $title ) {
        $this->title = $title;
    }
 
    public function __toString() {
        return $this->title;
    }
}
 
$storage = new SplObjectStorage();
$obj = new StorageTest( "wiki.cc" );
$storage->attach( $obj );
$obj2 = new StorageTest( "eide.org" );
$storage->attach( $obj2 );
 
foreach( $storage as $o ) {
        echo $o;
        echo "\n";
}
?>

And this will, as you most likely would think, display the following:

wiki.cc
eide.org

The SplObjectStorage class implements Iterator and Countable, so we can use the storage object as any other objects that implement these. Just look at this:

1
echo count($storage );

Will output “2″

Adding the same object

The SplObjectStorage is, as the name suggests, a storage, so what will happen if we add the same object twice?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
/**
 *  Test class that we will store in the
 *  SplObjectStorage object.
 */
class StorageTest {
    private $title;
 
    public function __construct( $title ) {
        $this->title = $title;
    }
 
    public function __toString() {
        return $this->title;
    }
}
 
$storage = new SplObjectStorage();
$obj = new StorageTest( "www.eide.org" );
$storage->attach( $obj );
$storage->attach( $obj );
 
foreach( $storage as $o ) {
        echo $o;
        echo "\n";
}
?>

We now get:

www.eide.org

as output. So: the SplObjectStorage object can tell if you add the same object more than one time, this way we can keep adding N objects to the storage, and we can be sure that when we iterate over the object we will only get unique objects.

Updating objects

What then, if we update a object, will we get more than one object when we iterate over the storage?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
 
/**
 *  Test class that we will store in the
 *  SplObjectStorage object.
 */
class StorageTest {
    private $title;
 
    public function __construct( $title ) {
        $this->title = $title;
    }
 
    public function __toString() {
        return $this->title;
    }
 
    public function setTitle( $title ) {
        $this->title = $title;
    }
}
 
$storage = new SplObjectStorage();
$obj = new StorageTest( "wiki.cc" );
$storage->attach( $obj );
$obj->setTitle( "eide.org" );
 
$storage->attach( $obj );
 
foreach( $storage as $o ) {
        echo $o;
        echo "\n";
}
?>

We now get:

eide.org

So: we can see that the storage object keeps track of the fact that we are manipulating the same object, and we can safely manipulate objects when adding them to the storage.

Check for objects added

With a storage like SplObjectStorage it is always interesting to check if a certain item has been added or not, this feature is covered with the contains() function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
 
/**
 *  Test class that we will store in the
 *  SplObjectStorage object.
 */
class StorageTest {
    private $title;
 
    public function __construct( $title ) {
        $this->title = $title;
    }
 
    public function __toString() {
        return $this->title;
    }
}
 
$storage = new SplObjectStorage();
$obj = new StorageTest( "wiki.cc" );
$storage->attach( $obj );
$obj2 = new StorageTest( "eide.org" );
 
if( $storage->contains( $obj ) ) {
    echo "storage contains the object\n";
} else {
    echo "storage does NOT contain the object\n";
}
if( $storage->contains( $obj2 ) ) {
    echo "storage contains the object\n";
} else {
    echo "storage does NOT contain the object\n";
}
?>

This will give us the following output:

storage contains the object
storage does NOT contain the object

And you can see that SplObjectStorage correctly detects which of the two objects that has been added to it.

Detaching objects

With adding objects there always comes the time when you want to remove a object: this is covered by the detach() function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
 
/**
 *  Test class that we will store in the
 *  SplObjectStorage object.
 */
class StorageTest {
    private $title;
 
    public function __construct( $title ) {
        $this->title = $title;
    }
 
    public function __toString() {
        return $this->title;
    }
}
 
$storage = new SplObjectStorage();
$obj = new StorageTest( "eide.org" );
$storage->attach( $obj );
if( $storage->contains( $obj ) ) {
    echo "storage contains the object\n";
} else {
    echo "storage does NOT contain the object\n";
}
$storage->detach( $obj );
if( $storage->contains( $obj ) ) {
    echo "storage contains the object\n";
} else {
    echo "storage does NOT contain the object\n";
}
?>

This will give us:

storage contains the object
storage does NOT contain the object

Finally

The SplObjectStorage object is a nice addition to the SPL family that will ease the use of object collections without worrying about what objects you already have added to the mix.

2 comments to “SplObjectStorage”

You can leave a reply or Trackback this post.
  1. Piccolo Principe says: -#1

    Nice general purpose class.. Spl is very useful as its OO approach make OO programming in php easier as developers don’t have to reinvent the wheel every time an iterator is needed.. I think it is ‘the right way’ of writing php code.
    Now this SplObjectStorage will be a cute candidate for subclassing to make complex objects..

Write a Reply or Comment

Your email address will not be published.