Fun with Array Interfaces

As a programmer who works with different languages every day, I find a lot of joy in learning how things are done differently in other languages and seeing if I can do the same in PHP. One thing I liked in particular in Python was how one can emulate features of native data types in custom classes.

We have to get some things out of the way though. First create a Twitter account if you don't have one yet. Now sign up for a developer account and generate an access token and secret.

Next, download or clone the code from Github and run composer install inside the source folder. If you're unfamiliar with Composer, see SitePoint's previous article on it. Open the index.php file and add in the necessary Oauth data.

The Countable Interface

The Countable interface is probably the most self explanatory. It lets us pass objects to the count() method simply by implementing the count method.

We can get the number of tweets for a user by doing a GET request on "/users/show".

With offsetUnset we could also do a delete by tweet id, but I'll leave that up to you to implement.

Unfortunately, implementing offsetSet does not make much sense. For things like this, the easy way out is to just throw a custom exception like UnsupportedOperationException. But on the other hand, it may depend on your application's specific business rules as well.

The Iterator Interface

I have reserved the interface I like the most for last! The Iterator interface is extremely useful here because I don't think there is a better way to encapsulate the gory details of paging through a remote collection than looping through our timeline object as if it were a normal array.

In our example, we are going to loop through the tweets in our timeline by chronologically retrieving chunks of tweets and then storing them in a buffer. We will iterate through this buffer until it runs out and then we got another batch of tweets using the id of the last tweet as offset.

Initially we have none and this is where the rewind method comes in: to get the latest 10 tweets so have an offset from where we can get the next 10.

The valid() method is just there to indicate whether or not to continue looping. This can be done by checking if our buffer of tweets is emtpy:

public function valid()
{
return !empty($this->tweets);
}

The key() and current() methods simply return the key and value of the current tweet in our iteration. For our purposes, we will simply get the tweet id and the text of the latest tweet from our buffer.

Finally there is the next method. Here we dequeue the head of our buffer to get the next element to iterate on. Then, we ensure we get the next set of tweets if we are at the last element of our buffer.

We are done! That was a very basic implementation of looping through a user's tweets. There is a lot more that can be done like caching locally to save on api calls but that's the beauty of using interfaces: they allow us to change our strategy under the hood and as long as our implementation is still correct, we can expect it to still work.

But for now, you can watch our timeline object working hard by running php index.php at the command line.

Conclusion

The benefit of Interfaces is two-fold. They let us encapsulate implementation details and afford us syntactic sugar, both of which can be a real charm in any application that asks for interoperability. If you have any questions or comments, please leave them in the comments section below!

Jeune has a fascination for building and solving things. Right now, he is interested in data mining, algorithms, performance, and software design. When not in front of his laptop, he cooks mean Asian dishes or is out kicking ass on the football (soccer) field.