6. Interfaces
An interface is a structure that defines method prototypes. A class that implements an interface must define the code for all of the interface’s methods.
6.1. The script tree

6.2. A first interface
We define an interface [IExample] in a script [IExample.php]. In this same script, we define two classes that implement the [IExample] interface:
<?php
// strict adherence to function parameter types
declare(strict_types=1);
// namespace
namespace Exemples;
// an interface
interface IExemple {
// interface methods
public function ajouter(int $i, int $j): int;
public function soustraire(int $i, int $j): int;
}
// implementation 1 of the IExemple interface
class Classe1 implements IExemple {
public function ajouter(int $a, int $b): int {
return $a + $b + 10;
}
public function soustraire(int $a, int $b): int {
return $a - $b + 20;
}
}
// implementation 2 of the IExemple interface
class Classe2 implements IExemple {
public function ajouter(int $a, int $b) : int{
return $a + $b + 100;
}
public function soustraire(int $a, int $b) : int {
return $a - $b + 200;
}
}
Comments
- lines 10–14: The IExample interface defines two methods: the add function (line 12) and the subtract function (line 13). The interface does not define the code for these methods. The classes that implement the interface will do so;
- line 17: The Class1 class implements the IExample interface. It therefore defines code for the add method (line 18) and the subtract method (line 22);
- lines 29–38: same for the Class2 class;
We use the [IExemple] interface in the following [interfaces-01.php] script:
<?php
require_once "IExemple.php";
use \Exemples\Classe1;
use \Exemples\Classe2;
use \Exemples\IExemple;
// function
function calculer(int $a, int $b, IExemple $interface) : void {
print $interface->ajouter($a, $b)."\n";
print $interface->soustraire($a, $b)."\n";
}
// ------------------- hand
// creation of 2 objects of type Class1 and Class2
$c1 = new Classe1();
$c2 = new Classe2();
// call the calculate function
calculer(4, 3, $c1);
calculer(14, 13, $c2);
Comments
- lines 3–6: inclusion and definition of the classes and interfaces used by the script;
- line 3: instead of the include statement, we have used the require_once statement here. The include statement includes a file in the current script even if it has already been included, whereas the require_once statement includes it only once. Therefore, when it comes to including code, we prefer the require_once statement;
- Lines 9–12: We define a function;
- Line 9: Here, we declare the types of the three parameters. If, at runtime, the actual parameter is not of the expected type, an error is thrown. The third parameter is of type [IExample]. This means that the actual parameter must be an instance of a class that implements the [IExample] interface; in our example, this means an instance of the [Class1] or [Class2] classes;
- Lines 10–11: We use the [add, subtract] methods of the [IExample] interface;
- line 19: the third actual parameter is of type [Class1], which is compatible with the [IExample] type of the function’s third formal parameter;
- line 20: same for the [Class2] class;
Results
6.3. Deriving an Interface
Just as a child class can extend a parent class, a child interface can extend a parent interface.
Consider the [IExample2] interface defined in the [IExample2.php] file:
<?php
// strict adherence to function parameter types
declare(strict_types=1);
// namespace
namespace Exemples;
// interface definition IExemple included
require_once __DIR__."/IExemple.php";
// an interface derived from IExemple
interface IExemple2 extends IExemple {
// the interface method
public function multiplier(int $i, int $j): int;
}
// implementation of IExemple2 interface
class Classe3 extends Classe2 implements IExemple2 {
public function multiplier(int $a, int $b): int {
return $a * $b;
}
}
Comments
- line 6: the interface [IExample2] will be in the same namespace as the interface [Iexample];
- line 9: the definition file for the [Iexample] interface is included;
- lines 12–15: define the interface [IExample2], which extends (inherits from) the interface [IExample] and adds a new method to it (line 14);
- lines 18–24: the class [Class3] extends the class [Class2]. Since [Class2] implements the interface [IExample], [Class3] will also implement it. In fact, [Class3] inherits all the public and protected methods of the [Class2] class, including the add and subtract methods. Furthermore, we specify that [Class3] implements the [IExample2] interface. As such, it must also implement the multiply method, which [Class2] does not. This is what lines 20–22 do;
The [IExample2] interface is used by the following [interfaces-02] script:
<?php
// strict adherence to function parameter types
declare(strict_types=1);
// inclusion and qualification of classes and interfaces required by the script
require_once __DIR__."/Iexemple2.php";
use \Exemples\IExemple2;
use \Exemples\Classe3;
// function
function calculer(int $a, int $b, IExemple2 $interface) {
print $interface->ajouter($a, $b) . "\n";
print $interface->soustraire($a, $b) . "\n";
print $interface->multiplier($a, $b) . "\n";
}
// ------------------- hand
// creation of 1 Class3 object implementing IExemple2
$c3 = new Classe3();
// call the calculate function
calculer(4, 3, $c3);
Comments
- line 12: the third parameter of the [calculate] function is of type [IExample2];
- lines 13–15: the three methods of the [IExample2] interface are used;
- line 22: the [calculate] function is called with an object of type [IExample2] as the third parameter (line 20);
Results
6.4. Passing an Interface as a Function Parameter
We saw in the previous section that when the expected type for a function parameter is a class, the actual parameter can be an object of the expected type or a derived type. The same applies to interfaces, as shown in the following script [interfaces-03.php]:
<?php
// strict adherence to function parameter types
declare(strict_types=1);
// inclusion and qualification of classes and interfaces required by the script
require_once __DIR__."/IExemple.php";
use \Exemples\IExemple;
require_once __DIR__."/IExemple2.php";
use \Exemples\Classe3;
// function
function calculer(int $a, int $b, IExemple $interface) {
print $interface->ajouter($a, $b) . "\n";
print $interface->soustraire($a, $b) . "\n";
}
// ------------------- hand
// creation of 1 object of type Class3 which implements IExemple2 and therefore IExemple
$c3 = new Classe3();
// call the calculate function
calculer(4, 3, $c3);
Comments
- line 13: the [calculate] function expects a type [IExample] as its third parameter. This means that the actual parameter type can be [IExample] or a derived type;
- line 20: we instantiate an object $c3 of type [Class3], a class that implements the interface [IExample2], which itself extends the interface [IExample]. So ultimately, $c3 implements the interface [IExample];
- line 22: we call the function [calculate] with an object $c3 of type [Class3] as the third parameter. Through the interplay of class inheritance and implementations, we saw that the object $c3 implements the type [IExample]. We can therefore use it as the third parameter;
Results