PHP 接口


在本教程中,我们将学习如何使用PHP接口,这是PHP面向对象编程中最重要的构建块之一。

PHP 接口介绍

接口允许您定义一个类必须实现哪些方法。

要定义接口,可以使用interface关键字,如下所示:

1
2
3
4
<?php
interface IMyInterface{
// 各种方法
}

接口由尚未实现的方法组成。换句话说,接口的所有方法都是抽象方法。接口可以有自己的常量。语法如下:

1
2
3
4
5
6
7
8
<?php
interface IMyInterface{
const INTERFACE_CONSTANT_1 = 1;
const INTERFACE_CONSTANT_2 = 'a string';
 
public function method_1();
public function method_2();
}

接口中的所有方法都必须是public的。

当我们要声明一个重用了现有类的属性和方法的新类时,我们说子类继承自或扩展了父类。
但是对于接口,我们说一个类实现了一个接口。一个类只能从一个类继承,而一个类可以实现一个或多个接口。

要实现一个接口,可以使用implements操作符:

1
2
3
4
5
6
7
8
class MyClass implements IMyInterface{
public function method_1(){
// 方法1的实现
}
public function method_2(){
// 方法2的实现
}
}

当一个类实现一个接口时,我们也称它为一个具体的类。具体类必须实现接口中具有相同名称和参数的所有方法。

一个类不能同时实现两个具有相同方法名称的接口,因为这样会导致调用的方法不确定。

与类类似,还可以使用extends操作符来扩展一个接口,如下所示:

1
2
3
4
5
6
7
interface IReadable{
public function read();
}
 
interface IWritable extends IReadable{
public function write();
}

IWritable接口通过添加一个write()抽象方法扩展了IReadable接口。

为什么我们要在PHP中使用接口?

有几个原因:

  • 通过实现接口,对象的调用者只需要关心对象的接口,而不需要关心对象方法的实现。因此,可以在不影响接口调用者的情况下变更具体的实现。
  • 接口允许不相关的类实现同一组方法,而不用管它们在类继承层次结构中的位置如何。
  • 接口使您能够对多重继承进行建模,因为一个类可以实现多个接口,而它只能扩展一个类。

PHP接口示例

在下面的示例中,我们将向您展示如何使用接口使系统变得更易于扩展和更灵活。

假设,我们必须创建一个可以记录消息的日志记录器。

首先,我们将创建一个名为ILogger的接口,如下所示:

1
2
3
4
<?php
interface ILogger{
public function log($message);
}

其次,我们可以创建一个FileLogger类,它将日志消息写入日志文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
require_once 'ilogger.php';
class FileLogger implements ILogger {
private $handle;
private $logFile;
public function __construct($filename, $mode = 'a') {
$this->logFile = $filename;
// 打开用于追加内容的日志文件
$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类:

1
2
3
4
5
6
7
8
9
10
11
<?php
require_once 'classes/filelogger.php';
function testFilelogger() {
$logger = new FileLogger('./log.txt', 'w');
$logger->log('开始使用文件记录器');
$logger->log('另一条日志消息');
}
testFilelogger();

然后,我们可以添加一个数据库日志,实现ILogger接口如下:

为了演示,我们将DBLogger类写得尽可能地简化。

1
2
3
4
5
6
7
8
<?php
require_once 'ilogger.php';
class DBLogger implements ILogger {
public function log($message) {
echo sprintf("记录 %s 到数据库中\n", $message);
}
}

我们可以很容易地添加实现ILogger接口的其他类型的日志记录器,而不需要修改现有的日志记录器。

下面的代码片段演示了如何同时使用多个使用了同一个ILogger接口的记录器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
function testLoggers() {
$loggers = array(
new FileLogger('./log.txt'),
new DBLogger()
);
foreach ($loggers as $logger) {
$logger->log('Log message');
}
}
testLoggers();


原文链接:https://codingdict.com/