Login

Coding Examples of the Iterator, Countable and ArrayAccess SPL Interfaces in PHP 5

Welcome to the final installment of a series that provides an overview of the Iterator, Countable and ArrayAccess SPL interfaces in PHP 5. Made up of six parts, this series teaches you how to build a fully-working MySQL abstraction class that takes advantage of the methods inherited from these native interfaces to manipulate database record sets easily by using an array syntax.

In the articles that preceded this one I demonstrated in a step-by-step fashion how to develop such a MySQL handling class. It effectively defined all of the methods required by the aforementioned interfaces. In doing so, the class now is not only capable of traversing data sets by way of a plain “foreach” construct, but it allows you to count and access rows in those sets as if they were array elements.

Of course, while describing the functionality of this sample class is fine, bragging about it is only the half of the story. It’s necessary to show a few examples of how to use the class in a useful way. Therefore, in this last part of the series I’m going to code for you a few basic scripts that will show the actual functionality of this implementing class.

Before I start coding some sample scripts that show how to work with the implementing “MySQLi_ResultWrapper” class, I’d like to reintroduce its definition, just in case you haven’t had the chance to study it in depth. So, here’s how this class was developed:

Since this class has been discussed in previous part of the series, I’m not going to waste your time (and mine) explaining how it works. Instead, I suggest you pay attention to the class below, which is an implementer of the Iterator, Countable and ArrayAccess SPL interfaces mentioned in the introduction:

// determine if result set pointer is valid or not (implementation required by ‘valid()’ method in Iterator interface)

public function valid()

{

return $this->_pointer < $this->num_rows;

}

// determine if the given offset exists (implementation required by ‘offsetExists()’ method in ArrayAccess interface)

public function offsetExists($offset)

{

$this->movePointer($offset);

$row = $this->fetchObject();

return isset($row);

}

// get row according to given offset (implementation required by ‘offsetExists()’ method in ArrayAccess interface)

public function offsetGet($offset)

{

$this->_pointer = abs((int)$offset);

return $this->current();

}

// not implemented (required by ‘offsetSet()’ method in ArrayAccess interface)

public function offsetSet($offset, $value){}

// not implemented (required by ‘offsetUnset()’ method in ArrayAccess interface)

public function offsetUnset($offset){}

// free up result set

public function __destruct()

{

$this->close();

}

}

While the definition of the above “MySQLi_ResultWrapper” class is somewhat long, it is easy to follow, since most of its methods are inherited from the Iterator, Countable and ArrayAccess native interfaces. At this point, you’ll surely be wondering what this buys us. Well, as I explained in the introduction, thanks to this inheritance, the class can be used to manipulate MySQL data sets as if they were plain PHP arrays.

To demonstrate this, though, it’s necessary to code some scripts that show the veracity of this claim. Therefore, in the following segment I’m going to write an example that will show how to utilize an instance of the “MySQLi_ResultWrapper” class to traverse a simple database result set.

To learn how this example will be coded, click on the link below and keep reading.

{mospagebreak title=Putting the MySQLi_ResultWrapper class to work}

If you’re like me, then you want to learn how to work with the previous “MySQLi_ResultWrapper” class, right? Below I coded a script that shows the benefits of making this class an implementer of the Iterator interface.

As the above code sample shows, it’s extremely easy to traverse a database result set by using a “foreach” loop. Once the data have been fetched from a sample “users” table, thanks to the implementation of the Iterator interface, traversing the records is a breeze. In addition, the example demonstrates how to explicitly use the “rewind(),” “current()” and “key()” methods, which allow you to freely navigate the result set.

So far, so good. Now that you’ve grasped the logic driving the previous code sample, it’s time to show how to use the “count(),” “offsetExists()” and “offsetGet()” methods. This example will be the appropriate conclusion to this tutorial, so click on the link that appears below and read the following segment.

{mospagebreak title=Final script: counting rows in a result set and accessing specified records}

As I said in the section that you just read, I’m going to finish this tutorial by coding an example that demonstrates how to use the “count(),” “offsetExists()” and “offsetGet()” methods implemented by the “MySQLi_ResultWrapper” class. These will allow you to count rows in a given result set, as well as access specified elements in it.

Once again, the earlier code fragment shows in a nutshell why implementing the Countable and ArrayAccess SPL interfaces is so convenient. In this particular case, the methods inherited from the interfaces are used to determine the number of rows contained in a data set, and to access a specific record by its offset.

And with this last example, I’m finishing this article that explores the Iterator, Countable and ArrayAccess interfaces packaged with the Standard PHP Library. Feel free to edit all of the code fragments shown in this article. Doing this will surely give you more ideas for how to implement these interfaces in a few other creative ways.

Final thoughts

Sad but true, we’ve come to the end of this series. Hopefully, the code samples shown in its six parts will give you a good idea of how to implement the Iterator, Countable and ArrayAccess SPL interfaces within different classes.

As you saw for yourself, in this particular case the interfaces were implemented by a class that processes MySQL result sets, but naturally they can be used for constructing classes that will handle different data collections, such as XML nodes and flat text files rows. The possibilities and endless.