Software Design

PHP Interfaces: what they are, and why you should be using them

A lot of people have been using PHP for a long time. It makes sense; it’s a language that has been designed for and makes it easy to put content (and I use the term loosely) on the web. Unfortunately, just because something has been designed for a specific purpose doesn’t mean that it does it well. Call it another can of worms, but PHP before major version 5 (with a reworked object model) was miserable to work with on any level beyond “here is my procedural code, please show me my banner ad filler… I mean, website now.”

Fortunately, steps have been taken to fix this, and the later versions of PHP (starting with 5.0, but especially since 5.3) have started providing us with tools to actually develop, instead of just code (more on that distinction another day). One of the features introduced with PHP 5 (and the one I want to focus on in this post) was the concept of object interfaces. From the documentation:

> Object interfaces allow you to create code which specifies which methods a class must implement, without having to define how these methods are handled.

Put simply, an interface is a contract between the concrete implementation of a class and any code that uses it. It says, in effect, “I promise that I will implement these methods, and that they will be publicly accessible to your code.” That’s the entirety of the contract; an interface doesn’t (and in fact, can’t) dictate the implementation of the contracted methods, just their existence. If a class implements the interface iCookable with methods bake() and checkTemp(), nothing is stopping it from implementing bake() to launch carrier pigeons and checkTemp() to release a bunch of balloons into the sky.

Given an effort to remain semantically compatible, however, a class that implements a given interface can expose a public API and hide all of its implementation details: the entire internal workings of the class could be thrown out and rewritten, and code that uses the class would never even have to know or care.

A practical example

So why should you care about all of this? Well, imagine that you are composing a class to add tags to an object (which could represent a blog post, a user comment, or something else entirely). Without using interfaces, your tag() method might look something like this:

That’s all well and good, but what if the object passed to the method doesn’t provide a publicly accessible addTag() method? Furthermore, what if $object is not actually an object at all, but a string or an array? Even if you’re writing the entire codebase yourself, accidents still happen, and if not, you lose even more control. You could do something like this…

… but this is tedious, and violates the principle of Don’t Repeat Yourself if you have to add the same code over and over again for every method relating to your taggable objects. A better solution is to create an interface that contracts to provide methods needed for tagging.

Note that while it’s good practice to explicitly declare visibility for your class methods and properties, method signatures defined by an interface are inherently public, so I figure that you can get away with saving a few keystrokes.

Also note that I’ve gone ahead and added a basic docblock that documents both the arguments the method should take (in this case, a string representing the tag we’re adding to the object), and what it should return (in this case, nothing). Since PHP does not allow us to hint a method’s return type or the more primitive variable types (string, integer, boolean, etc), docblocks are a great way to encourage the semantic compatibility we were talking about earlier.

Okay, now we have an interface that guarantees the methods we need for tagging. Back in our tag() method, let’s implement it:

Simple as that. We no longer have to wonder if $object will, in fact, be an object, or whether it will provide the methods we need to add tags to it, and we don’t have to couple the tag() method to a concrete implementation of a taggable object. Any class can implement our TaggableInterface, and if the implementation is rational, our code can expect to be able to add tags to that class until the end of the world.

tl;dr

You can use interfaces to ensure that the functionality your code needs will be accessible, without tying yourself to a particular implementation of that functionality.

3 thoughts on “PHP Interfaces: what they are, and why you should be using them

  1. Very helpful overview of interfaces and a great look on how to implement them. Thanks for the time you took putting this together.

Leave a Reply