Summary: in this tutorial, you will learn about the PHP interface and how to use an interface to define a contract between classes.
Introduction to the PHP interface
An interface allows you to specify a contract that a class must implement. To define an interface, you use the interface
keyword as follows:
<?php
interface MyInterface
{
//...
}
Code language: HTML, XML (xml)
An interface consists of methods that contain no implementation. In other words, all methods of the interface are abstract methods. An interface can also include constants. For example:
<?php
interface MyInterface
{
const CONSTANT_NAME = 1;
public function methodName();
}
Code language: HTML, XML (xml)
Note that all the methods in the interface must be public.
When you define a class (child class) that reuses properties and methods of another class (parent class), the child class extends the parent class.
However, for interfaces, we say that a class implements an interface.
A class can inherit from one class only. Howeer, it can implement multiple interfaces.
To define a class that implements an interface, you use the implements
keyword as follows:
<?php
interface MyInterface
{
const CONSTANT_NAME = 1;
public function methodName();
}
class MyClass implements MyInterface
{
public function methodName()
{
// ...
}
}
Code language: HTML, XML (xml)
When a class implements an interface, it’s called a concrete class. The concrete class needs to implement all the methods of the interface.
Like a class, an interface can extend another interface using the extends
keyword. The following example shows how the Document
interface extends the Readable
interface:
interface Readable
{
public function read();
}
interface Document extends Readable
{
public function getContents();
}
Code language: PHP (php)
Why should you use PHP interfaces?
The following are reasons for using interfaces:
- By implementing an interface, the object’s caller needs to care only about the object’s interface, not implementations of the object’s methods. Therefore you can change the implementations without affecting the caller of the interface.
- An interface allows unrelated classes to implement the same set of methods, regardless of their positions in the class inheritance hierarchy.
- An interface enables you to model multiple inheritances because a class can implement more than one interface.
PHP interface example
In the following example, we will show you how to use the interface to make the system more flexible and easier to extend. Suppose you have to create a logger that can log a message.
First, create an interface called Logger
as follows:
<?php
interface Logger
{
public function log($message);
}
Code language: HTML, XML (xml)
Second, create a FileLogger
class that writes the log messages to a file:
<?php
interface Logger
{
public function log($message);
}
class FileLogger implements Logger
{
private $handle;
private $logFile;
public function __construct($filename, $mode = 'a')
{
$this->logFile = $filename;
// open log file for append
$this->handle = fopen($filename, $mode)
or die('Could not open the log file');
}
public function log($message)
{
$message = date('F j, Y, g:i a') . ': ' . $message . "\n";
fwrite($this->handle, $message);
}
public function __destruct()
{
if ($this->handle) {
fclose($this->handle);
}
}
}
Code language: HTML, XML (xml)
Third, use the FileLogger
class as follows:
<?php
$logger = new FileLogger('./log.txt', 'w');
$logger->log('PHP interfae is awesome');
Code language: HTML, XML (xml)
The following adds another logger that logs information to the database. For demonstration purposes, we make the DatabaseLogger
class as simple as possible:
<?php
class DatabaseLogger implements Logger
{
public function log($message)
{
echo sprintf("Log %s to the database\n", $message);
}
}
Code language: HTML, XML (xml)
And you can easily add other kinds of loggers that implement the Logger
interface without touching existing loggers.
The following code snippet demonstrates how to use multiple loggers at the same time using a single ILogger
interface:
$loggers = [
new FileLogger('./log.txt'),
new DatabaseLogger()
];
foreach ($loggers as $logger) {
$logger->log('Log message');
}
Code language: PHP (php)
Put it all together.
<?php
interface Logger
{
public function log($message);
}
class FileLogger implements Logger
{
private $handle;
private $logFile;
public function __construct($filename, $mode = 'a')
{
$this->logFile = $filename;
// open log file for append
$this->handle = fopen($filename, $mode)
or die('Could not open the log file');
}
public function log($message)
{
$message = date('F j, Y, g:i a') . ': ' . $message . "\n";
fwrite($this->handle, $message);
}
public function __destruct()
{
if ($this->handle) {
fclose($this->handle);
}
}
}
class DatabaseLogger implements Logger
{
public function log($message)
{
echo sprintf("Log %s to the database\n", $message);
}
}
// examle 1
$logger = new FileLogger('./log.txt', 'w');
$logger->log('PHP interfae is awesome');
// example 2
$loggers = [
new FileLogger('./log.txt'),
new DatabaseLogger()
];
foreach ($loggers as $logger) {
$logger->log('Log message');
}
Code language: HTML, XML (xml)
Note that in the real-world application, you should separate interfaces and classes in separate files.
Summary
- PHP interface provides a contract for other classes to follow (or implement).