PHP Interfaces Explained

How Interfaces work in PHP (with examples)

PHP interfaces

In this tutorial you will learn about PHP Interfaces.

Let’s find out what Interfaces are, how to use them (with examples) and how they differ from abstract classes.

Contents


What are Interfaces, and how do they work in PHP?

Object Interfaces, or just interfaces, are PHP structures that define a set of methods.

Classes can implement interfaces. When a class implements an interface, that class must also implement all the interface’s methods.

Interfaces are similar to abstract classes, but with some important differences.

Most importantly, interfaces can only define public constants and methods. Moreover, interfaces only specify the signature of the methods (that is, the method’s name and argument list), without the actual implementation.

Interfaces are defined similarly to classes, but you must use the interface keyword instead of the class keyword.

Let’s look at an example right away:


/* Define an interface called "Rotatable". */
interface Rotatable
{
   /* Interface methods must be public and without the body. */
   public function rotateRight(float $angle);
   public function rotateLeft(float $angle);
}

Rotatable is an Interface.

It contains two methods: rotateRight(), and rotateLeft().

When a class implements the Rotatable interface, that class must also implement these methods.

The idea is that if a class implements Rotatable it means that it can rotate left and right, and therefore it must provide the interface methods.

 

So, how do you use an interface, in practice?

Let’s say that you have a kitchen planner web application. (You know, one of those apps where you can design and plan your room).

A kitchen can contain objects: walls, appliances such as fridges and toasters, tables, chairs, and so on.

Some of these objects, like tables and chairs, can be rotated. Others, like walls and fridges, cannot.

Each kitchen object has a corresponding PHP class. The ones that can be rotated implement the Rotatable interface.

Like this:


/* The "implements" keyword makes a class implement an interface. */
class Table implements Rotatable
{
   /* All the interface's methods must be implemented in the class. */
   public function rotateRight(float $angle) {
      //…
   }
   
   public function rotateLeft(float $angle) {
      //…
   }
}

class Chair implements Rotatable
{
   public function rotateRight(float $angle) {
      //…
   }
   
   public function rotateLeft(float $angle) {
      //…
   }
}
 

The Table and Chair classes implement the Rotatable interface.

When they do so, they also must implement the interface methods, that is: rotateRight() and rotateLeft().

Therefore, for every class that implements Rotatable, you can always call the rotateRight() and rotateLeft() methods.

For example:


$table = new Table();
$chair = new Chair();
$kitchen = [$table, $chair];
foreach ($kitchen as $kitchenObject)
{
   $kitchenObject->rotateRight(90);
}
 

Now, you may ask: can’t we just define rotateLeft() and rotateRight() inside an abstract class, and then let Table and Chair inherit from that class?

Well, technically, yes.

However, if you do so then all classes that can rotate need to inherit from the same base class. But this is not always a good solution.

For example, both tables and toasters can rotate, but they have nothing in common. It would not make sense for them to inherit from the same base class, right?

The opposite problem exists, too.

For example, toasters and fridges are both “appliances”, and it makes sense for them to inherit from a common base appliance class. But while toasters can be rotated, fridges cannot.

Interfaces solve this problem, because classes can implement them regardless of their parent classes.

How to check a class’ interfaces: class_implements().

How do you know if a class implements a specific interface?

You can use the class_implements() function.

This function takes an object or a class name as its argument, and returns an array of the interfaces implemented by that class.

For example:


/* A class that does not implement Rotatable. */
class Wall {}
$table = new Table(); /* Implements Rotatable. */
$wall = new Wall(); /* Does not implement Rotatable. */

$tableInterfaces = class_implements($table);
$wallInterfaces = class_implements($wall);
echo "Table interfaces: ";
print_r($tableInterfaces);
echo "<br><br>";
echo "Wall interfaces: ";
print_r($wallInterfaces);
echo "<br><br>";

The output will be:


Table interfaces: Array ( [Rotatable] => Rotatable )
Wall interfaces: Array ( )
 

By using this function, you can selectively call an interface’s methods only on the objects that implement it.

Like this:


$table = new Table();
$chair = new Chair();
$wall = new Wall();
$kitchen = [$table, $chair, $wall];
foreach ($kitchen as $kitchenObject)
{
   if (in_array('Rotatable', class_implements($kitchenObject)))
   {
      /* Only $table and $char arrive here. */
      $kitchenObject->rotateRight(90);
   }
}

Interfaces syntax and rules.

Let’s recap what you have learned so far:

  • The interface keyword defines a new PHP interface.
  • The implements keyword makes a class implement an interface.

Interfaces can only contain:

  • Public methods, with their signature only (name and argument list) and without the body.
  • Public constants.
 

Note: PHP interfaces do not have constructors.

 

When a class implements an interface, the class must implement all the interface’s methods.

There is one exception: if an abstract class implements an interface, it does not need to implement all the interface’s methods. However, non-abstract children of that class must complete the implementation.

For example:


/* An interface with a constant and two methods. */
interface Colors
{
   const DEFAULT_COLOR = 'green';
   public function changeColor(string $newColor);
   public function getColor();
}
/* This abstract class implements one interface method only. */
abstract class Color implements Colors
{
   private $color;
   
   public function getColor() {
      return $this->color;
   }
}
/* This child class completes the implementation of the other interface method. */
class MyColor extends Color
{
   public function changeColor(string $newColor) {
      echo 'Color set to: ' . $newColor;
   }
}
 

The interface’s constants become available in the classes that implement it.

For example:


$myColor = new MyColor();
echo "Default color: " . MyColor::DEFAULT_COLOR;
echo "<br>";
$myColor->changeColor('red');

Default color: green
Color set to: red

Interfaces and inheritance.

Interfaces can use inheritance like classes do, with the difference that interfaces inherit from other interfaces.

Just to make it clear: interfaces can only inherit from other interfaces, and not from classes.

Inheritance in interfaces follows the same rules as class inheritance. In particular, methods and constants are inherited from the parent interface.

For example:


interface CanWalk
{
   public function walk();
}
/* Use the extends keyword to inherit from another interface. */
interface CanRun extends CanWalk
{
   public function run();
}
class Leopard implements CanRun
{
   /* Must implement walk() and run() */
   public function walk() {
      //...
   }
   
   public function run() {
      //...
   }
}

Implementing multiple interfaces.

A PHP class can implement multiple interfaces.

To do that, you need to separate the interface names with a comma.

For example:


interface CanRun
{
   public function run();
}
interface CanSwim
{
   public function swim();
}
class Tiger implements CanRun, CanSwim
{
   /* Must implement run() and swim() */
   public function run() {
      //...
   }
   
   public function swim() {
      //...
   }
}
 

Note:

If two interfaces provide the same method, you cannot implement both interfaces in the same class, unless both methods take the same arguments.

For example, the following code is wrong because the two rotateRight() methods take different arguments:


interface Rotatable
{
   public function rotateRight(float $angle);
}
interface Movements
{
   public function moveForward();
   public function rotateRight();
}
class MyClass implements Rotatable, Movements
{
   //...
}

Fatal error: Declaration of Rotatable::rotateRight(float $angle) must be compatible with Movements::rotateRight()
 

However, the following code is correct because the two methods share the same arguments:


interface Rotatable
{
   public function rotateRight(float $angle);
}
interface Movements
{
   public function moveForward();
   public function rotateRight(float $angle);
}
class MyClass implements Rotatable, Movements
{
   //...
}

Interfaces VS abstract classes.

Interfaces are similar to abstract classes.

But there are some fundamental differences:

  • Interfaces cannot have properties, while abstract classes can.
  • Interface methods and constants must be public.
  • Methods in an interface are abstract by default, and they cannot have the body. Abstract classes, on the other hand, can contain both abstract and non-abstract methods.

When should you use a PHP interface instead of an abstract class?

In a nutshell, there are two advantages in using interfaces:

  • When a class implements an interface, the caller only needs to know the interface’s methods signatures. The methods share the same signature (that is, name and arguments) among all the classes that implement the interface, without the need for those classes to inherit from the same base class.
  • Classes can implement multiple interfaces. This is the closest way to simulate “multiple inheritance” in PHP, as PHP does not support true multiple inheritance.
 

Here’s a comparison table:

Abstract ClassesInterfaces
Can have constants, methods and properties.Can only have constants and methods.
Support public, protected and private visibility.Only support public constants and methods.
Can have abstract and non-abstract methods.All methods are abstract by default.
Methods (public and protected) are available to children classes.Methods are available to every class that implements the interface.
Classes can inherit from one other class only.A class canimplement multiple interfaces.

Conclusion

In this tutorial you learned how PHP interfaces work.

To recap:

  • You can define an interface with the interface keyword.
  • Interfaces contain public constants and method signatures (without the body).
  • Classes can implement interfaces with the implements keyword. A class can implement multiple interfaces.
  • When a class implements an interface, that class must implement all the interface’s methods.
  • You can see which interfaces a class implements by using the class_implements() function.
  • Interfaces can inherit from other interfaces.

Do you have any questions? Then leave a comment below and I’ll get back to you.

And be sure to subscribe to my free newsletter to get my weekly tips!

Alex

Image copyright: Teamwork people vector created by pch.vector – www.freepik.com

Leave a Comment