Painless Data Traversal with PHP FilterIterators
There’s load of ways to traverse data, especially in PHP where there are a variety of loops available; including while, do while, for and foreach. These are fine for normal structures, such as scalar and associative arrays. But what if you want to get a bit more fancy? Enter the FilterIterator
There’s load of ways to traverse data, especially in PHP where there are a variety of loops available; including while, do while, for and foreach. These are fine for normal structures, such as scalar and associative arrays. But what if you want to get a bit more fancy?
Say you started out with a structure similar to the following:
You can see that you could quickly and simple filter the information using any of the previously mentioned loops. The following is a rather trivial example of how you could do just this.
This would display output similar to the following:
But say, over time, the the data structure grew in complexity and you wanted to filter out some records, but not others. I’m sure that one of your first reactions would, naturally, be to change the SQL query - assuming that we’re talking to a datasource that is an RDBMS. But:
- What if it wasn’t?
- What if your only access was an API?
- What if you were not allowed to change the underlying code?
- What if you didn’t know all the ramifications of what a change may be?
It’s not quite so easy is it? Let’s say that one or more of these constraints is in effect. Is there an answer? Yes, there most certainly is - so long as you’re using PHP >= 5.1.0 that is.
Enter the FilterIterator
That’s right, in PHP 5.1.0 as part of the SPL (Standard PHP Library), Filter Iterators were introduced. If you’ve not heard of them or used them, the PHP manual describes them as:
This abstract iterator filters out unwanted values. This class should be extended to implement custom iterator filters. The FilterIterator::accept() must be implemented in the subclass.
Iterators and the FilterIterator are a wonderful addition to the PHP language as they allow us, as developers, to apply the existing looping constructs to our custom data structures.
Recently in a Malt Blue project, we were tasked with building a project that provides data, that is largely similar in nature, which needed to be viewed across a range of different parts of the application. Given that the data was so similar in nature, it made no sense to write a series of different, utility, functions for it - which would then need to be maintained over time.
So we chose to instead implement a series of FilterIterators so that we could make one data request call and display the same information in a multitude of, slightly, different ways.
For the purposes of this example, let’s assume that the data structure is similar to the above. Have a look at the code below and we’ll work through it, showing how to implement a FilterIterator:
In the code above, we define the class MyIterator_Filter_InActive which extends FilterIterator. The FilterIterator interface requires us to only implement one method: accept. If accept returns true, then the current record is displayed. If it returns false, then the record is skipped.
So, we retrieve the current record, with $value = $this->current();. We then check whether it has an active value and if that value is set. If it is, then we return it. If one of these conditions is not met, then we automatically return false.
So let’s instantiate the FilterIterator with our existing dataset and see what the result is.
As our data is already in an array, we start by using it to instantiate an ArrayIterator, which makes it painless to iterate over the whole dataset - not what we want. This instantiated ArrayIterator is then passed to our custom FilterIterator.
With this instantiated FilterIterator, we can then loop over the data as before, but now only with records that have active set as true - as the below code does:
The updated output will be as below:
Pretty simple, hey? Now yes, this was a simple example. But you can see how, through creating a custom FilterIterator, you can quickly and simply use the existing PHP looping constructs to iterate through your custom data sets returning only the information that you specifically need.
Do you use FilterIterators already? What’s your experience with them? Do they help you build more maintainable code? Share your experience in the comments. If you liked this post, then check out the follow up to it: filter by date of birth easily with a filteriterator.
You might also be interested in...
- Filter By Date Of Birth Easily with a FilterIterator
- Zend Form Mastery with Zend Config – Part 3 Standard Form & Element Options
- Zend Form Mastery with Zend Config - Part 2 Core Form Configuration
- Zend Form Mastery with Zend Config - Part 1 Custom Filter Paths
- Beginning cloud development with cloudControl – Part 4 – Memcache
comments powered by Disqus