PHP Interface

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).
Did you find this tutorial useful?