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 Examples;
// an interface
interface IExample {
// interface methods
public function add(int $i, int $j): int;
public function subtract(int $i, int $j): int;
}
// Implementation 1 of the IExample interface
class Class1 implements IExample {
public function add(int $a, int $b): int {
return $a + $b + 10;
}
public function subtract(int $a, int $b): int {
return $a - $b + 20;
}
}
// Implementation 2 of the IExample interface
class Class2 implements IExample {
public function add(int $a, int $b) : int{
return $a + $b + 100;
}
public function subtract(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 \Examples\Class1;
use \Examples\Class2;
use \Examples\IExample;
// function
function calculate(int $a, int $b, IExample $interface) : void {
print $interface->add($a, $b)."\n";
print $interface->subtract($a, $b)."\n";
}
// ------------------- main
// Create 2 objects of type Class1 and Class2
$c1 = new Class1();
$c2 = new Class2();
// call the calculate function
calculate(4, 3, $c1);
calculate(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 Examples;
// Include the definition of the IExample interface
require_once __DIR__."/IExample.php";
// an interface that extends IExample
interface IExample2 extends IExample {
// the interface method
public function multiply(int $i, int $j): int;
}
// implementation of the IExample2 interface
class Class3 extends Class2 implements IExample2 {
public function multiply(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__."/Iexample2.php";
use \Examples\Example2;
use \Examples\Class3;
// function
function calculate(int $a, int $b, IExample2 $interface) {
print $interface->add($a, $b) . "\n";
print $interface->subtract($a, $b) . "\n";
print $interface->multiply($a, $b) . "\n";
}
// ------------------- main
// Create an object of type Class3 that implements IExample2
$c3 = new Class3();
// call the calculate function
calculate(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__."/IExample.php";
use \Examples\IExample;
require_once __DIR__."/IExample2.php";
use \Examples\Class3;
// function
function calculate(int $a, int $b, IExample $interface) {
print $interface->add($a, $b) . "\n";
print $interface->subtract($a, $b) . "\n";
}
// ------------------- main
// Create an object of type Class3 that implements IExample2 and therefore IExample
$c3 = new Class3();
// call the calculate function
calculate(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