PHP 可迭代对象
1. 什么是可迭代对象 (Iterable)?
iterable 是 PHP 7.1 引入的一种伪类型(pseudo-type)。它接受任何可以被 foreach 循环遍历的值。
既然一个变量可以被循环,那么它就符合 iterable 的定义。这在函数参数或返回值中非常有用,因为它允许函数同时接受数组和实现了 Iterator 接口的对象,而无需分别定义不同的类型约束。
2. 使用 Iterable 作为参数
函数可以接受一个可迭代对象作为参数。任何数组或实现了 Iterator 接口的对象都可以传入该参数。
代码示例:
<?php
function printIterable(iterable $myIterable) {
foreach($myIterable as $item) {
echo $item;
}
}
$arr = ["a", "b", "c"];
printIterable($arr);
?>3. 使用 Iterable 作为返回值
函数也可以返回一个可迭代对象。这告诉调用者,返回的结果可以被 foreach 遍历。
代码示例:
<?php
function getIterable(): iterable {
return ["a", "b", "c"];
}
$myIterable = getIterable();
foreach($myIterable as $item) {
echo $item;
}
?>4. 创建可迭代对象
数组和实现了 Iterator 接口的对象都被视为 iterable。
4.1 数组 (Arrays)
所有的数组都是可迭代的,因此它们可以传递给任何要求 iterable 类型的函数。
4.2 迭代器 (Iterators)
任何实现了 Iterator 接口的对象都可以作为可迭代对象使用。迭代器包含一个记录在列表中位置的指针,以及用于在列表中导航的方法。
如果您的数据模型过于复杂,无法用简单的数组表示,但您仍希望能够使用 foreach 遍历它,那么实现 Iterator 接口是最佳解决方案。
5. Iterator 接口详解
要实现 Iterator 接口,类必须包含以下五个方法,以便 foreach 循环能够正确执行:
current()- 返回当前指针指向的元素。它可以是任何数据类型。key()- 返回与列表中当前元素关联的键(Key)。next()- 将指针移动到列表中的下一个元素。rewind()- 将指针重置到列表的开头。valid()- 如果指针当前指向的元素存在,则返回 true,否则返回 false(循环在此终止)。
5.1 实战示例:自定义迭代器
下例展示了如何实现 Iterator 接口并创建一个可迭代对象:
代码示例:
<?php
// 创建一个迭代器类
class MyIterator implements Iterator {
private $items = [];
private $pointer = 0;
public function __construct($items) {
// array_values 确保数组具有数字索引
$this->items = array_values($items);
}
public function current() {
return $this->items[$this->pointer];
}
public function key() {
return $this->pointer;
}
public function next() {
$this->pointer++;
}
public function rewind() {
$this->pointer = 0;
}
public function valid() {
// 检查指针位置是否存在对应的元素
return $this->pointer < count($this->items);
}
}
// 使用该迭代器
$myIter = new MyIterator(["苹果", "香蕉", "樱桃"]);
foreach($myIter as $key => $value) {
echo "$key: $value <br>";
}
?>开发建议: 使用 iterable 类型提示可以显著增强代码的通用性。例如,在编写数据导出函数时,声明接受 iterable 参数,意味着该函数既可以处理现成的数组,也可以处理从数据库中逐条获取数据的生成器(Generator)或迭代器对象,从而有效控制内存占用。