PHP イテラブル (Iterables)
1. PHPにおけるイテラブルとは?
PHPにおいて、イテラブル(iterable)とは foreach() ループで反復処理ができる値のことです。
iterable という擬似型(pseudo-type)は PHP 7.1 で導入されました。これは、関数の引数(arguments)や戻り値(return values)のデータ型として使用することができます。
イテラブルとして扱えるのは、配列(array)、または Iterator インターフェースを実装したオブジェクトです。
2. イテラブルの使用方法
iterable キーワードは、関数のパラメータ(引数)の型指定や、関数の戻り値の型として使用できます。
2.1 イテラブルな引数を持つ関数の例
<?php
function printIterable(iterable $x) {
foreach($x as $item) {
echo $item;
}
}
// 配列(array)を使用して呼び出し
printIterable(["a", "b", "c"]);
// オブジェクト(Iterator)を使用して呼び出し
$iterator = new ArrayIterator(["d", "e", "f"]);
printIterable($iterator);
?>2.2 イテラブルな戻り値を持つ関数の例
<?php
function getIterable(): iterable {
return ["a", "b", "c"];
}
foreach(getIterable() as $item) {
echo $item;
}
?>3. イテラブルの作成
3.1 配列 (Arrays)
すべての配列は自動的にイテラブルです。したがって、イテラブルを要求する関数の引数として、あらゆる配列を使用することができます。
3.2 イテレータ (Iterators)
Iterator インターフェースを実装している任意のオブジェクトは、イテラブルを要求する関数の引数として使用できます。
イテレータはアイテムのリストを保持し、それらをループで処理するためのメソッドを提供します。内部的にリスト内の要素の1つを指すポインタ(pointer)を保持しており、各アイテムは検索に使用できるキー(key)を持つ必要があります。
Iterator インターフェースを実装する場合、以下のメソッドを定義する必要があります:
current()- ポインタが現在指している要素を返します。データ型は任意です。key()- リスト内の現在の要素に関連付けられたキーを返します。型は integer, float, boolean, string のいずれかです。next()- ポインタをリスト内の次の要素に移動させます。rewind()- ポインタをリストの最初の要素に戻します。valid()- 内部ポインタがどの要素も指していない場合(例:リストの最後でnext()が呼ばれた後など)はfalseを返します。それ以外の場合はtrueを返します。
4. Iteratorインターフェースの実装例
実際に Iterator インターフェースを実装し、それをイテラブルとして使用する例を見てみましょう。
<?php
// イテレータ(Iterator)の作成
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() {
// count() はリスト内に何個のアイテムがあるかを返します
return $this->pointer < count($this->items);
}
}
// イテラブルを使用する関数
function printIterable(iterable $myIterable) {
foreach($myIterable as $item) {
echo $item;
}
}
// 作成したイテレータをイテラブルとして使用する
$iterator = new MyIterator(["a", "b", "c"]);
printIterable($iterator);
?>