Интерфейс позволяет вам указать контракт, который должен реализовать класс. Чтобы определить интерфейс, вы используете ключевое слово interface следующим образом:
<?php
interface MyInterface
{
//...
}
Интерфейс состоит из методов, не содержащих реализации. Другими словами, все методы интерфейса - абстрактные методы. Интерфейс также может включать константы. Например:
<?php
interface MyInterface
{
const CONSTANT_NAME = 1;
public function methodName();
}
Обратите внимание, что все методы в интерфейсе должны быть общедоступными (public).
Когда вы определяете класс (дочерний класс), который повторно использует свойства и методы другого класса (родительский класс), дочерний класс расширяет родительский класс.
Однако для интерфейсов мы говорим, что класс реализует или имплеиентирует интерфейс.
Класс может наследовать только от одного класса. Тем не менее, он может реализовывать несколько интерфейсов.
Чтобы определить класс, реализующий интерфейс, мы используем ключевое слово implements следующим образом:
<?php
interface MyInterface
{
const CONSTANT_NAME = 1;
public function methodName();
}
class MyClass implements MyInterface
{
public function methodName()
{
// ...
}
}
Когда класс реализует интерфейс, он называется конкретным классом. Конкретный класс должен реализовывать все методы интерфейса.
Как и класс, интерфейс может расширять другой интерфейс с помощью ключевого слова extends. В следующем примере показано, как интерфейс Document расширяет интерфейс Readable:
interface Readable
{
public function read();
}
interface Document extends Readable
{
public function getContents();
}
Почему следует использовать интерфейсы PHP?
В следующем примере мы покажем вам, как использовать интерфейс, чтобы сделать систему более гибкой и простой в расширении. Предположим, вам нужно создать регистратор, который может регистрировать сообщения.
Сначала создайте интерфейс под названием Logger следующим образом:
<?php
interface Logger
{
public function log($message);
}
Во-вторых, создайте класс FileLogger, который записывает сообщения журнала в файл:
<?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);
}
}
}
В-третьих, используйте класс FileLogger следующим образом:
<?php
$logger = new FileLogger('./log.txt', 'w');
$logger->log('PHP interfae is awesome');
Следующее добавляет еще один регистратор, который регистрирует информацию в базе данных. В демонстрационных целях мы максимально упрощаем класс DatabaseLogger:
<?php
class DatabaseLogger implements Logger
{
public function log($message)
{
echo sprintf("Log %s to the database\n", $message);
}
}
И вы можете легко добавить другие виды логгеров, которые реализуют интерфейс Logger, не затрагивая существующие классы.
Следующий фрагмент кода демонстрирует, как использовать несколько средств ведения журнала логов одновременно с помощью одного интерфейса ILogger:
$loggers = [
new FileLogger('./log.txt'),
new DatabaseLogger()
];
foreach ($loggers as $logger) {
$logger->log('Log message');
}
<?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');
}
Обратите внимание, что в реальном приложении вы должны разделять интерфейсы и классы в отдельных файлах.