本文目录导读:

我来详细介绍 PHP 迭代器的使用方法和原理。
什么是迭代器
迭代器是一种设计模式,它允许你遍历集合(数组、对象等)中的元素,而不需要了解底层的数据结构。
基本迭代器接口
PHP 提供了 Iterator 接口,实现它需要定义 5 个方法:
<?php
class MyIterator implements Iterator {
private $data = [];
private $position = 0;
public function __construct(array $data) {
$this->data = $data;
$this->position = 0;
}
// 返回当前元素
public function current() {
return $this->data[$this->position];
}
// 返回当前键
public function key() {
return $this->position;
}
// 移动到下一个元素
public function next() {
$this->position++;
}
// 重置位置到开头
public function rewind() {
$this->position = 0;
}
// 检查当前位置是否有效
public function valid() {
return isset($this->data[$this->position]);
}
}
// 使用示例
$iterator = new MyIterator(['apple', 'banana', 'orange']);
foreach ($iterator as $key => $value) {
echo "$key => $value\n";
}
?>
使用内置迭代器
PHP 提供了多种内置迭代器:
ArrayIterator
<?php
$data = ['a' => 1, 'b' => 2, 'c' => 3];
$iterator = new ArrayIterator($data);
foreach ($iterator as $key => $value) {
echo "$key => $value\n";
}
// 修改迭代器内容
$iterator->offsetSet('d', 4);
$iterator->append(5);
?>
IteratorIterator
<?php
$array = [1, 2, 3, 4, 5];
$iterator = new ArrayIterator($array);
// 包装迭代器
$wrapped = new IteratorIterator($iterator);
foreach ($wrapped as $value) {
echo $value . " ";
}
?>
实用迭代器类
FilterIterator - 过滤迭代器
<?php
class EvenFilter extends FilterIterator {
public function accept() {
return $this->current() % 2 === 0;
}
}
$numbers = new ArrayIterator([1, 2, 3, 4, 5, 6]);
$evens = new EvenFilter($numbers);
foreach ($evens as $value) {
echo $value . " "; // 输出: 2 4 6
}
?>
LimitIterator - 限制数量
<?php
$array = new ArrayIterator(['a', 'b', 'c', 'd', 'e']);
$limit = new LimitIterator($array, 1, 3); // 从第1个开始取3个
foreach ($limit as $key => $value) {
echo "$key => $value\n"; // 输出: 1 => b, 2 => c, 3 => d
}
?>
CachingIterator - 缓存迭代器
<?php
$array = new ArrayIterator(['a', 'b', 'c']);
$caching = new CachingIterator($array);
foreach ($caching as $key => $value) {
echo "$key => $value";
if ($caching->hasNext()) {
echo " (有下一个)";
}
echo "\n";
}
?>
RecursiveIteratorIterator - 递归迭代器
<?php
$array = [
'fruit' => [
'apple', 'orange'
],
'vegetables' => [
'carrot', 'potato'
]
];
$iterator = new RecursiveIteratorIterator(
new RecursiveArrayIterator($array),
RecursiveIteratorIterator::SELF_FIRST
);
foreach ($iterator as $key => $value) {
echo "$key => $value\n";
}
?>
使用生成器实现迭代器
生成器是一种更简单的实现迭代器的方式:
<?php
function getEvenNumbers($limit) {
for ($i = 0; $i <= $limit; $i++) {
if ($i % 2 === 0) {
yield $i; // 生成值
}
}
}
foreach (getEvenNumbers(10) as $number) {
echo $number . " "; // 输出: 0 2 4 6 8 10
}
// 带键的生成器
function getConfig() {
yield 'host' => 'localhost';
yield 'port' => 3306;
yield 'dbname' => 'test';
}
foreach (getConfig() as $key => $value) {
echo "$key: $value\n";
}
?>
实际应用示例
大文件处理
<?php
class FileLineIterator implements Iterator {
private $file;
private $line;
private $position;
public function __construct($filename) {
$this->file = fopen($filename, 'r');
$this->position = 0;
}
public function current() {
return $this->line;
}
public function key() {
return $this->position;
}
public function next() {
$this->line = fgets($this->file);
$this->position++;
}
public function rewind() {
rewind($this->file);
$this->position = 0;
$this->line = fgets($this->file);
}
public function valid() {
return $this->line !== false;
}
public function __destruct() {
fclose($this->file);
}
}
// 处理大文件
$fileIterator = new FileLineIterator('large_file.txt');
foreach ($fileIterator as $lineNumber => $line) {
echo "Line $lineNumber: $line";
}
?>
数据库结果集迭代
<?php
class DatabaseIterator implements Iterator {
private $result;
private $currentRow;
private $position = 0;
public function __construct($result) {
$this->result = $result;
}
public function current() {
return $this->currentRow;
}
public function key() {
return $this->position;
}
public function next() {
$this->currentRow = fetch_assoc($this->result);
$this->position++;
}
public function rewind() {
mysqli_data_seek($this->result, 0);
$this->position = 0;
$this->currentRow = fetch_assoc($this->result);
}
public function valid() {
return $this->currentRow !== null;
}
}
?>
迭代器与数组对照
| 特性 | 数组 | 迭代器 |
|---|---|---|
| 内存占用 | 一次性加载全部 | 按需加载 |
| 遍历性能 | 快 | 稍慢但更灵活 |
| 数据修改 | 可能影响遍历 | 可控遍历 |
| 大数据量 | 可能内存溢出 | 内存友好 |
| 流式处理 | 不支持 | 支持 |
最佳实践
- 处理大数据时使用迭代器避免内存问题
- 延迟计算 - 生成器特别适合
- 数据转换 - 使用迭代器链式处理数据
- 自定义遍历逻辑时使用迭代器
- 与 foreach 兼容 - 自动使用迭代器
<?php
// 链式迭代器示例
class UppercaseIterator extends IteratorIterator {
public function current() {
return strtoupper(parent::current());
}
}
$array = ['hello', 'world'];
$iterator = new UppercaseIterator(new ArrayIterator($array));
foreach ($iterator as $value) {
echo $value . " "; // 输出: HELLO WORLD
}
?>
迭代器是 PHP 中处理数据遍历的强大工具,合理使用可以大大提升代码的质量和性能。