PHP Interfaces, Traits, and Inheritance, how and when to use them

Hi all

So this one is going to be fairly short and simple, I hope! What I am going to cover, and this does assume so prior knowledge, is what interfaces, traits, and inheritance are; and some different use cases for them.

So the first one, and maybe the easiest one to cover, first:

Inheritance

In its simplest term, and I’m going to try and keep things simple in this article. In very brief terms, inheritance is about extending something which exists. Of course, you may well have created this base on which you’re extending.

Simple use case: User class, extended by an Administrator class. This would be because that an Administrator can do everything a user can do, but a User can’t necessarily do everything an Administrator can do.

The way you would do this in PHP would look like:

class User
{
    // Regardless of whether you're a standard user or an administrator you would have access to this method
    public function getUserId() : int
    {
        return $this->id;
    }
}

class Administrator extends User
{
    // Only administrators can delete users
    public function deleteUser(int $userId)
    {
        // Do something here
    }
}

Of course, there are a million ways of using this, but essentially what you’re doing here is following a single line of inheritance, each extension gaining its own functionality. Something else of note is that you can override (except where theĀ final keyword is used) methods and classes.

There are many ways you might want to do this, including several layers of inheritance, or multiple classes extending the same base.

Interfaces

This is concept defines a set of interfaces (or integration points), though the key theme here is that an interface can be applied to anything. You’re specifying very little, except that the class implementing this interface must abide by the rules laid out.

interface Notifiable
{
    public function getEmailAddress() : string;
}

Now the thing to note here is that the interface simply doesn’t care how you retrieve that email address, but you must have a way of doing it, and any class this is applied to must follow those rules.

The easiest use case for an interface, that I can think of, is something like the above. Notifiable, anything within your system could be notifiable. An instance of the system, a user, an organisation, a team or department. It doesn’t matter, applying the interface means that it could be parsed and handled, through a notification service.

Traits

I’ve tried to explain this one recently, and the use case for it. The easiest way I found of explaining it recently has been: An interface lets you define the input and output of some methods, inheritance lets you gain functionality from parent classes. Traits are for where you don’t want to use parent classes (because you can only extend one class at a time), but want to bring the “meat” of some methods across.

At the risk of causing some controversy here (again) I’m going to say the easiest use case to explain with traits is a logging class, which might look something like

trait Logger
{
    // PSR-3 compliant functionality here
}

class MyThingDoer
{
    Use Logger;
}

All this does is allows the MyThingDoer class to do anything that the Logger trait specified.

In Summary

I’m not necessarily advocating the use of these three sets of functionality, or how they should be used, or anything like that. I’m simply documenting their existence and usage in a way that those moving from PHP procedurally into a structured OOP environment might understand it.

I understand there are dependency injection arguments regarding traits, and I think that is a conversation for another day.

So, in a sentence. When you want to have a base class, and things which logically make sense to be extensions – use inheritance. When you want to ensure conformity to a set of rules, so that objects can be parsed into service providers, use interfaces. When you want to simply share functionality across multiple classes, use traits.

I hope this has helped, of course, if you have anything to add, anything you’d like to say or anything to contribute, stories, personal experiences, etc. as always feel free to drop it in the comments.

One Comment

  1. Pingback:Layering Software Design on new or existing code bases

I'd love to hear your opinion on what I've written. Anecdotes are always welcome.

This site uses Akismet to reduce spam. Learn how your comment data is processed.