Filter By Date Of Birth Easily with a FilterIterator
If you have a list of people and want to find only the people with a date of birth in a set year or greater, there’s nothing easier than a FilterIterator. Find out how today.
There are a lot of ways to traverse data in PHP, including while, do while, for and foreach loops. These are fine in a lot of cases. But what if you want to reuse looping logic or have somewhat complex logic? Enter the FilterIterator.
Say you started out with a structure similar to the following:
<?php
$dataList = [
[
'name' => 'John Citizen',
'email' => 'johnc@citizen.org',
'dob' => 1350910989,
'location' => 'Brisbane, Qld, Australia',
'active' => true
],
[
'name' => 'Jane Citizen',
'email' => 'janec@citizen.org',
'dob' => 1350910989,
'location' => 'Townsville, Qld, Australia',
'active' => false
],
[
'name' => 'Peter Walker',
'email' => 'peterw@citizen.org',
'dob' => 1350910989,
'location' => 'Sydney, Nsw, Australia',
'active' => false
],
[
'name' => 'Wendy Hardworker',
'email' => 'wendyh@citizen.org',
'dob' => 1350910989,
'location' => 'Melbourne, Vic, Australia',
'active' => true
],
[
// ...
],
);
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.
<?php
foreach ($dataList as $userDetail) {
printf(
"Name: %s | Email: %s | Date Of Birth: %s | Location: %s",
$userDetail["name"],
$userDetail["email"],
$userDetail["dob"],
$userDetail["location"]
);
}
This would display output similar to the following:
Name: John Citizen | Email: johnc@citizen.org | DOB: 1350910989 | Location: Brisbane, Qld, Australia
Name: Jane Citizen | Email: janec@citizen.org | DOB: 1350910989 | Location: Townsville, Qld, Australia
Name: Peter Walker | Email: peterw@citizen.org | DOB: 1350910989 | Location: Sydney, Nsw, Australia
Name: Wendy Hardworker | Email: wendyh@citizen.org | DOB: 1350910989 | Location: Melbourne, Vic, Australia
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:
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.
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:
<?php
class MyIterator_Filter_InActive extends FilterIterator
{
public function accept()
{
$value = $this->current();
if (
array_key_exists('active', $value)
&& ! empty($value['active'])
)
{
return $value['active'];
}
return false;
}
}
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.
<?php
$dataIterator = new MyIterator_Filter_InActive(
new ArrayIterator($dataList)
);
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:
<?php
foreach ($dataIterator as $userDetail) {
printf(
"Name: %s | Email: %s | Date Of Birth: %s | Location: %s",
$userDetail["name"],
$userDetail["email"],
$userDetail["dob"],
$userDetail["location"]
);
}
The updated output will be as below:
Name: John Citizen | Email: johnc@citizen.org | DOB: 1350910989 | Location: Brisbane, Qld, Australia
Name: Wendy Hardworker | Email: wendyh@citizen.org | DOB: 1350910989 | Location: Melbourne, Vic, Australia
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.
If you have a list of people and want to find only the people with a date of birth in a set year or greater, there’s nothing easier than a FilterIterator. Find out how today.
I was going through PHPDeveloper this morning and found a great post from NetTuts from December 27th, 2011 entitled: 10 New Year’s Resolutions Every Web Developer Should Make.
As developers, we can believe errors are negative reflections on our applications. But are they really so? In today’s post, I show you how they’re anything but negative, they’re actually very very positive, when interpreted correctly.
Whether you’re a casual freelance php developer or running a professional freelance business, you’ll know just how much work can be involved. Not only do you have applications to design, develop and support. But you’ve also got business functions such as marketing, advertising, finances and networking as well. In this post we show you a tool to massively reduce your workload - FreeAgent.
Please consider buying me a coffee. It really helps me to keep producing new tutorials.
Join the discussion
comments powered by Disqus