DEV Community

loading...
Cover image for Make sense of PHP interfaces

Make sense of PHP interfaces

jmau111 profile image Julien Maury Originally published at blog.julien-maury.dev Updated on ・2 min read

Indeed PHP interfaces have a purpose.

They are contracts, like instruction manuals for other developers.
However, it might be difficult to understand why interfaces are useful.

Basics

An interface is an abstract class therefore you cannot instantiate it. Instead, you will implement it.

Here is a very basic example:

interface MyInterface {
    public function setName(string $name);
    public function getName();
}

class MyClass implements MyInterface {
    private $name; 

    public function setName(string $name) { 
        $this->name = $name; 
    }

    public function getName() {
        return $this->name; 
    }
}
Enter fullscreen mode Exit fullscreen mode

MyClass must implement setName() and getName(). If you don't do that, you will get a fatal error:

Fatal error: Class MyClass contains 2 abstract methods and must therefore be declared abstract or implement the remaining methods (MyInterface::setName, MyInterface::getName)

Besides, all methods in interfaces must have public visibility scope and interfaces cannot have attributes.

The why

Developers use interfaces to describe how a class or a collection of classes should behave.

Interfaces encapsulate the implementation without handling the details for each class. But why?

Decoupling!

Interfaces allow you to change the implementation without changing the details a.k.a the way you use this implementation.

More advanced example

Any cache would need at least:

  • to store/set something in the cache
  • to get something in the cache
  • to delete something in the cache

For that purpose, we may create the following cache interface:

interface CacheInterface {
    public function set(string $key, $val);
    public function get(string $key);
    public function delete(string $key);
}
Enter fullscreen mode Exit fullscreen mode

This way, we can tell all developers to implement our cache interface without knowing the particular details of each use.

As a result, it's easy to change the caching system without changing the way it's used in the project.

The Symfony example

The previous example makes sense. Let's look at Symfony. When you want to implement any cache system, it's good practice to do the following:

use Symfony\Contracts\Cache\CacheInterface;

class MyClass {
    private $cache;
    public function __construct(CacheInterface $cache)
    {
        $this->cache = $cache;
    }
}
Enter fullscreen mode Exit fullscreen mode

Here we inject the cache implementation into our class (dependency injection). Next time we want to change the cache system, we won't have to modify our class at all.

Multiple implements vs multiple inheritances

PHP doesn’t support multiple inheritances. The following code is not possible:

class MyClass extends ClassX, ClassY {}
Enter fullscreen mode Exit fullscreen mode

This is partly because of the Diamond problem.

Instead, you could do:

class ClassY extends ClassX {}
class MyClass extends ClassY {}
Enter fullscreen mode Exit fullscreen mode

but ClassX and ClassY might handle different things so it does not make any sense to use inheritance.

If you want to enforce multiple behaviors, you can implement multiple interfaces.

class MyClass implements InterfaceX, InterfaceY {}
Enter fullscreen mode Exit fullscreen mode

In other words, you can group classes that share some functionality but do not share a parent class.

Wrap up

PHP interfaces are templates of method signatures for your classes. This is great for decoupling implementation and its use.

It's particularly useful when you need some flexibility while making sure all developers follow a set of rules.

Discussion (8)

Collapse
vlasales profile image
Vlastimil Pospichal

I don't like the suffix "Interface" in its name. Instead, I use the adjective property that the related object must have. This is good for understanding the role of the interface.

Collapse
bam92 profile image
Abel Lifaefi Mbula

Using "Interface" is just a tautology. It's not important at all although many devs/compagnies use it. I find useful arguments for not using that suffix in this post

Collapse
jmau111 profile image
Julien Maury Author

well, it might be a tautology, but the "creative" naming is rarely a good thing. Here, just with the name, you know what is. I'm not saying it's the perfect name, but it's usable.

Collapse
jmau111 profile image
Julien Maury Author

It depends. Symfony has a lot of Interfaces with that suffix, I guess the most important thing is to keep the same naming convention for consistency.

Collapse
vlasales profile image
Vlastimil Pospichal

I don't use Symfony, I am not limited by this choice.

For the consistency you may use proxies.

Collapse
taufik_nurrohman profile image
Taufik Nurrohman

You could also use traits.

Collapse
jmau111 profile image
Julien Maury Author

Hi, I agree you can indeed combine the use of traits with interfaces but you cannot use traits instead of interfaces. It depends on what you want to achieve.

Collapse
vlasales profile image
Vlastimil Pospichal

Traits are a highway to hell.

Forem Open with the Forem app