in PHP 5

Why Interfaces Rock

When I first learned PHP 5’s object oriented syntax and rules, I didn’t see much of a point to the interface options. I felt that I could do more by defining abstract classes and at least filling in some of the methods with some details. Lots of people in the PHP world still aren’t 100% sure the reasons that interfaces exist, or the best way to use them. However, interfaces are very cool, and anyone who does OOP in PHP should know about them.

To start, what is an interface? An interface is a collection of completely abstract methods. Interfaces do not contain any of the innerworkings of the application; instead, they serve the sole purpose in setting a structure for the objects that implement them. All of their methods must be public. Here is a sample interface:

<?php

interface DatabaseI
{
    public function __construct();

    public function connect();

    public function query();
}

&#91;/sourcecode&#93;

That doesn't look very interesting at all, and it's not, until we start getting into <a href="http://us2.php.net/manual/en/language.oop5.typehinting.php">type hinting</a> and using <a href="http://us2.php.net/manual/en/language.operators.type.php">instanceof</a> in PHP 5. This is where the power of interfaces comes into play.

As a developer, I've often wished there was a way to know that an object - any object - had implemented certain methods. With type hinting and the instanceof operator, it is now possible to determine whether or not an object has those methods, and interfaces make this even easier. Take for example:



class withoutTypeHinting
{
    public function __construct($databaseO)
    {
        if(method_exists('connect') {
            $databaseO->connect();
        }
    }
}

// Now let's use typehinting from our previous example

class withTypeHinting
{
    public function __construct(DatabaseI $databaseO)
    {
        $databaseO->connect();
    }
}

What’s the difference there? In the first example, we’re hoping that the method exists so that we can call it. We’ll have to throw an exception or do something if the connection doesn’t actually exist. But in the second example, we’re demanding an object that has implemented the methods in DatabaseI. We know that these methods must have been implemented, because we’re getting an instantiated object. So the method must exist.

Interfaces make it much easier to predict what methods will be available, and also to ensure that subclasses still conform to some semblance of the structure you’ve defined.

Interfaces are not without their drawbacks. One huge drawback of interfaces is that you must implement them precisely as they are defined; that is, because our __construct() method contained no arguments, you must either make your __construct() argument contain no arguments or set each argument to a value (e.g. __construct($a = true, $b = false); // etc). When defining an abstract class, and abstract methods, the rules of inheritance apply, making it possible to redefine the argument list. Also, because you have not defined anything but the method signature, you have no way of forcing it to return a particular type. Finally, you may not build an interface containing protected methods; you must use an abstract class for this.

Still, interfaces rock. They allow you to enforce the type of object and the methods that must be defined, and with type hinting you can always feel confident that a method is implemented, regardless of how that interface is extended.

Be the first to get Modern Object-Oriented PHP!

Long to learn how you can develop modern applications using object-oriented PHP? Curious about how to apply all these best practices to your code?

Modern Object-Oriented PHP is a brand-new book focused on teaching you the techniques you need for writing modern, well-designed object-oriented applications!

The book lands in April. Sign up today for a sample chapter plus special launch day discounts!

Powered by ConvertKit

16 Comments

  1. The other cool thing is that any object that implements an interface also inherits it’s type – so you can make a consuming object accept objects of only one type (via typehinting) – but then make a whole suite of consumables with different class names that implement an interface of the type required by the consumer. VERY handy.

  2. this is a fun syntax, too:

    interface SomeMarker {}

    class MarkedException implements SomeMarker {}

    try {
    throw new MarkedException;
    catch(SomeMarker $ex) {
    echo “isn’t it fun?”;
    }

  3. I love the ability to type hint with exceptions. It makes catching different exceptions that share the same parent or implement the same interface so easy.

  4. I probably won’t put a constructor in an interface since different implementations have different collaborators requirements. Commonly the creation of an object does not use polymorphism but it is abstracted away with a factory, since in many language you cannot do new $class(), and if you do it in php there is no type safety that the object will conform to an interface – type hinting for method parameters works only for already created objects.

  5. In software design this is called strategy pattern. It’s really cool that php5 really allows us to finally implement this paradigms.

  6. I love coding to the interface. They’re great for parallel development, too.

    I can adopt or design an interface and hand it off to a team member to code the internals. Meanwhile, I know what methods have been exposed so that I can interact with it.

    Interfaces help make objects more tangible. Think of your car stereo for example. If you go aftermarket, you have to buy an adapter to couple the interface of the stereo with the interface of the car’s wiring harness.

    Objects become more reusable when you know the interface and can write an adapter to pair two objects together.

  7. Hi Brandon!

    I just found this article today and your site looks also great (I’ve already added your feed to my Feedreader)… looking forward to read more posts!

    Have a nice day,

    Ever Daniel

  8. Another reason why I like interfaces is that methods which specify them as parameters are really easy to write unit tests for.

    Implement the interface in the unit test case, add the methods with the return values that you want to check and then have the test method pass itself to the method to be tested.

    Elegant, simple and reduces the need to mock objects.

  9. I use interfaces for plugin based architecture. When you use the type hinting that you specified (or ‘instanceof’), you can make sure that the plugin has at least defined the methods that your code requires. This way, when a user installs a new plugin, it at least won’t kill your software with a function not found type error. :)

  10. I’ve been thinking of writing about interfaces as well. Good stuff, but perhaps a bit difficult to understand.

    I have to agree with Giorgio in that your interface shouldn’t define the constructor – most languages don’t even let you – because classes implementing it often have different requirements and the constructor isn’t really a part of the object “surface”

  11. I’m pretty comfortable with who I am, and what I wrote. Feel free to counter-punch away. And you made some really good points.

  12. Hi Harry, seriously, the punch was a total miss ;- )

    After a while of using interfaces in PHP in larger projects that live for a while you will probably acknowledge the benefits.

    Unless you work at facebook you wont have to worry about delay caused by interfaces resolving at runtime. Please lets not get back into micro optimizations path ever again.

    PHP is not java nor other language, if you use for some time you will probably benefit from interfaces.

Comments are closed.