Iterator 介面定義
interface Iterator extends Traversable {
public function current(): mixed;
public function key(): mixed;
public function next(): void;
public function rewind(): void;
public function valid(): bool;
}
斐波那契迭代器完整實作
<?php
class Fibonacci implements Iterator {
private int $previous = 1;
private int $current = 0;
private int $key = 0;
public function current(): int {
return $this->current;
}
public function key(): int {
return $this->key;
}
public function next(): void {
// 核心遞推:F(n) = F(n-1) + F(n-2)
$newPrevious = $this->current;
$this->current += $this->previous;
$this->previous = $newPrevious;
$this->key++;
}
public function rewind(): void {
$this->previous = 1;
$this->current = 0;
$this->key = 0;
}
public function valid(): bool {
// 無限序列永遠有效,外部以 break/limit 控制
return true;
}
}
// 使用
$fib = new Fibonacci();
$i = 0;
foreach ($fib as $n) {
echo "$n ";
if (++$i >= 20) break;
}
// 輸出: 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
進階:加上限制的有限迭代器
class LimitedFibonacci implements Iterator {
private int $limit;
private int $count = 0;
// ... 同上 current/key/next/rewind ...
public function __construct(int $limit) {
$this->limit = $limit;
}
public function valid(): bool {
return $this->count < $this->limit;
}
public function next(): void {
parent::next(); // 假設繼承自 Fibonacci 或複製邏輯
$this->count++;
}
public function rewind(): void {
parent::rewind();
$this->count = 0;
}
}
foreach (new LimitedFibonacci(15) as $n) {
echo "$n ";
}
Generator 寫法 (PHP 5.5+,更簡潔)
function fibonacci(int $limit = INF): Generator {
$prev = 1;
$curr = 0;
for ($i = 0; $i < $limit; $i++) {
yield $curr;
[$prev, $curr] = [$curr, $prev + $curr];
}
}
foreach (fibonacci(20) as $n) {
echo "$n ";
}
應用場景
- 大數據集流式處理 (避免一次載入陣列)
- 資料庫游標封裝
- 檔案逐行讀取
- API 分頁自動迭代
- 無限數學序列 (質數、階乘、Collatz)
IteratorAggregate 替代方案
class FibonacciCollection implements IteratorAggregate {
private int $limit;
public function __construct(int $limit) { $this->limit = $limit; }
public function getIterator(): Traversable {
return new LimitedFibonacci($this->limit);
}
}
$coll = new FibonacciCollection(10);
foreach ($coll as $n) { ... }
// 可直接 count()、array_iterator() 等