PHP预定义接口是PHP内置的一些接口,这些接口提供了一些常用的功能和方法,可以方便开发者在编写代码时使用。常见的PHP预定义接口有Traversable、Iterator、IteratorAggregate、Throwable等,本教程将一一介绍。
一、Traversable接口
Traversable接口提供遍历集合的方法,如key、current、next等。
接口摘要:
interface Traversable {
}
这个接口没有任何方法,它的作用仅仅是作为所有可遍历类的基本接口。
二、Iterator接口
Iterator接口可在内部迭代自己的外部迭代器或类的接口。
interface Iterator extends Traversable {
/* 方法 */
public current(): mixed
public key(): mixed
public next(): void
public rewind(): void
public valid(): bool
}
基本示例:
这个例子展示了使用 foreach 时,迭代器方法的调用顺序。
<?php class myIterator implements Iterator { private $position = 0; private $array = array( "firstelement", "secondelement", "lastelement", ); public function __construct() { $this->position = 0; } public function rewind(): void { var_dump(__METHOD__); $this->position = 0; } #[\ReturnTypeWillChange] public function current() { var_dump(__METHOD__); return $this->array[$this->position]; } #[\ReturnTypeWillChange] public function key() { var_dump(__METHOD__); return $this->position; } public function next(): void { var_dump(__METHOD__); ++$this->position; } public function valid(): bool { var_dump(__METHOD__); return isset($this->array[$this->position]); } } $it = new myIterator; foreach($it as $key => $value) { var_dump($key, $value); echo "\n"; } ?>
以上示例的输出类似于:
string(18) "myIterator::rewind" string(17) "myIterator::valid" string(19) "myIterator::current" string(15) "myIterator::key" int(0) string(12) "firstelement" string(16) "myIterator::next" string(17) "myIterator::valid" string(19) "myIterator::current" string(15) "myIterator::key" int(1) string(13) "secondelement" string(16) "myIterator::next" string(17) "myIterator::valid" string(19) "myIterator::current" string(15) "myIterator::key" int(2) string(11) "lastelement" string(16) "myIterator::next" string(17) "myIterator::valid"
三、IteratorAggregate接口
IteratorAggregate(聚合式迭代器)接口用于创建外部迭代器。
interface IteratorAggregate extends Traversable {
/* 方法 */
public getIterator(): Traversable
}
基本用法:
<?php
class myData implements IteratorAggregate {
public $property1 = "Public property one";
public $property2 = "Public property two";
public $property3 = "Public property three";
public $property4 = "";
public function __construct() {
$this->property4 = "last property";
}
public function getIterator(): Traversable {
return new ArrayIterator($this);
}
}
$obj = new myData;
foreach($obj as $key => $value) {
var_dump($key, $value);
echo "\n";
}
?>
以上示例的输出类似于:
string(9) "property1" string(19) "Public property one" string(9) "property2" string(19) "Public property two" string(9) "property3" string(21) "Public property three" string(9) "property4" string(13) "last property"
四、Throwable接口
Throwable 是能被 throw 语句抛出的最基本的接口(interface),包含了 Error 和 Exception 。
注意:PHP 类无法直接实现 (implement) Throwable 接口,而应当去继承 Exception。
interface Throwable extends Stringable {
/* 方法 */
public getMessage(): string
public getCode(): int
public getFile(): string
public getLine(): int
public getTrace(): array
public getTraceAsString(): string
public getPrevious(): ?Throwable
public __toString(): string
/* 继承的方法 */
public Stringable::__toString(): string
}
五、ArrayAccess接口
ArrayAccess(数组式访问)接口提供像访问数组一样访问对象的能力。
interface ArrayAccess {
/* 方法 */
public offsetExists(mixed $offset): bool
public offsetGet(mixed $offset): mixed
public offsetSet(mixed $offset, mixed $value): void
public offsetUnset(mixed $offset): void
}
基础用法:
<?php
class Obj implements ArrayAccess {
public $container = [
"one" => 1,
"two" => 2,
"three" => 3,
];
public function offsetSet($offset, $value): void {
if (is_null($offset)) {
$this->container[] = $value;
} else {
$this->container[$offset] = $value;
}
}
public function offsetExists($offset): bool {
return isset($this->container[$offset]);
}
public function offsetUnset($offset): void {
unset($this->container[$offset]);
}
public function offsetGet($offset): mixed {
return isset($this->container[$offset]) ? $this->container[$offset] : null;
}
}
$obj = new Obj;
var_dump(isset($obj["two"]));
var_dump($obj["two"]);
unset($obj["two"]);
var_dump(isset($obj["two"]));
$obj["two"] = "A value";
var_dump($obj["two"]);
$obj[] = 'Append 1';
$obj[] = 'Append 2';
$obj[] = 'Append 3';
print_r($obj);
?>
以上示例的输出类似于:
bool(true) int(2) bool(false) string(7) "A value" obj Object ( [container:obj:private] => Array ( [one] => 1 [three] => 3 [two] => A value [0] => Append 1 [1] => Append 2 [2] => Append 3 ) )
六、Serializable接口
Serializable是自定义序列化的接口。
实现此接口的类将不再支持 __sleep() 和 __wakeup() 方法。当需要对实例进行序列化时,无论何时都会调用 serialize 方法。该方法不会自动调用 __destruct() 方法,除非在该方法中编写了相关功能,否则也不会产生副作用(side effect)。当数据被反序列化时,类将被正确识别并调用合适的 unserialize() 方法,而不是调用 __construct()。如果需要执行标准的构造函数,应该在 unserialize() 方法中进行处理。
interface Serializable {
/* 方法 */
public serialize(): ?string
public unserialize(string $data): void
}
基础用法:
<?php
class obj implements Serializable {
private $data;
public function __construct() {
$this->data = "My private data";
}
public function serialize() {
return serialize($this->data);
}
public function unserialize($data) {
$this->data = unserialize($data);
}
public function getData() {
return $this->data;
}
}
$obj = new obj;
$ser = serialize($obj);
var_dump($ser);
$newobj = unserialize($ser);
var_dump($newobj->getData());
?>
以上示例的输出类似于:
string(38) "C:3:"obj":23:{s:15:"My private data";}"
string(15) "My private data"
七、UnitEnum接口
UnitEnum 接口主要用于类型检测。引擎会自动应用 UnitEnum 接口到所有枚举类型,但用户自定义类不能实现该接口。由于引擎已经提供了枚举类型的默认实现,因此无法重载它的接口。
interface UnitEnum {
/* 方法 */
public static cases(): array
}
八、BackedEnum接口
BackedEnum接口它用于类型检测。引擎会自动应用 BackedEnum 接口到回退枚举。 用户自定义类不能实现该接口。 由于引擎已提供枚举的默认实现,因此不能重载它的接口。
interface BackedEnum extends UnitEnum {
/* 方法 */
public static from(int|string $value): static
public static tryFrom(int|string $value): ?static
/* 继承的方法 */
public static UnitEnum::cases(): array
}

