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 }