【PHP8.x】CallbackFilterIterator::__construct()メソッドの使い方
__constructメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
__constructメソッドは、フィルタリング機能を持つ新しいCallbackFilterIteratorのインスタンスを生成するコンストラクタです。このメソッドは、フィルタリングの対象となるイテレータと、そのフィルタリング条件を定義するコールバック関数の2つを引数として受け取ります。第一引数には、ArrayIteratorなど、PHPのIteratorインターフェースを実装したオブジェクトを指定します。このイテレータに含まれる各要素が、フィルタリング処理の対象となります。第二引数には、callable型のコールバック関数を指定します。この関数は、イテレータが持つ要素を一つずつ順番に評価するために呼び出されます。関数の内部で、現在の要素を残すべきかどうかを判定するロジックを記述し、結果としてtrueまたはfalseを返します。trueが返された要素だけが、新しく生成されたCallbackFilterIteratorのイテレーション結果に含まれ、falseが返された要素は除外されます。この仕組みにより、配列やオブジェクトの集合から特定の条件を満たすデータだけを柔軟に抽出することが可能になります。
構文(syntax)
1new CallbackFilterIterator(Iterator $iterator, callable $callback);
引数(parameters)
Iterator $iterator, callable $callback
- Iterator $iterator: フィルタリング対象となるイテレーターオブジェクト
- callable $callback: 各要素を評価するためのコールバック関数
戻り値(return)
戻り値なし
戻り値はありません
サンプルコード
PHP 8 コンストラクタプロパティ昇格でイテレータをフィルタリングする
1<?php 2 3/** 4 * PHP 8の「コンストラクタ プロパティ昇格」機能を使って、 5 * CallbackFilterIteratorと同様の機能を持つカスタムクラスを定義するサンプルです。 6 * 7 * FilterIteratorを継承し、コンストラクタで受け取ったコールバック関数を用いて 8 * イテレータの要素をフィルタリングします。 9 */ 10class MyCallbackFilter extends FilterIterator 11{ 12 /** 13 * コンストラクタ。 14 * プロパティ昇格 (Constructor Promotion) を利用して、 15 * 引数で受け取ったコールバック関数を直接 private プロパティとして宣言・初期化します。 16 * 17 * @param Iterator $iterator フィルタリング対象のイテレータ 18 * @param callable $callback 各要素を評価するコールバック関数。trueを返した要素のみが残る。 19 */ 20 public function __construct( 21 Iterator $iterator, 22 private readonly callable $callback 23 ) { 24 // 親クラスである FilterIterator のコンストラクタを呼び出します。 25 parent::__construct($iterator); 26 } 27 28 /** 29 * 現在の要素がフィルタ条件を満たすかどうかを判定します。 30 * FilterIterator によって実装が必須とされる抽象メソッドです。 31 * 32 * @return bool フィルタ条件を満たす場合は true、それ以外は false 33 */ 34 public function accept(): bool 35 { 36 // コンストラクタで受け取ったコールバック関数を実行し、その結果を返します。 37 // コールバックには、現在の要素の値とキーが渡されます。 38 return ($this->callback)($this->current(), $this->key()); 39 } 40} 41 42// --- 実行コード --- 43 44// 1から10までの数値を含む配列を作成します。 45$numbers = new ArrayIterator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); 46 47// 偶数のみを抽出するためのコールバック関数を定義します(アロー関数を使用)。 48$isEven = fn(int $num): bool => $num % 2 === 0; 49 50// カスタムフィルタクラスのインスタンスを生成します。 51$evenNumbersIterator = new MyCallbackFilter($numbers, $isEven); 52 53// フィルタリングされた結果をループ処理で出力します。 54echo "フィルタリング結果 (偶数のみ):\n"; 55foreach ($evenNumbersIterator as $number) { 56 echo $number . "\n"; 57} 58 59?>
このサンプルコードは、PHP 8の新機能「コンストラクタ プロパティ昇格」を使い、データの中から特定の条件に合う要素だけを抽出するオリジナルのフィルタ機能を持つクラスの作り方を示しています。
MyCallbackFilter クラスのコンストラクタ (__construct) は、第1引数 $iterator でフィルタリング対象の繰り返し可能なデータを、第2引数 $callback でどの要素を残すかを判断するための関数を受け取ります。ここで使われている「コンストラクタ プロパティ昇格」は、コンストラクタの引数に private のようなアクセス修飾子を付けるだけで、自動的にプロパティが宣言され、受け取った値が代入される機能です。これにより、従来必要だったプロパティ宣言と代入のコードを省略でき、記述が簡潔になります。
accept メソッドは、繰り返し処理の際に各要素に対して自動的に呼び出されます。このメソッドは、コンストラクタで受け取ったコールバック関数を実行し、その戻り値が true になった要素だけを有効なものとして扱います。
実行コードでは、1から10の数値を持つデータと「偶数かどうか」を判定する関数を MyCallbackFilter に渡しています。そのため、foreach で結果を一つずつ取り出すと、フィルタリングによって偶数のみが出力されます。
このサンプルコードはPHP 8の新機能「コンストラクタ プロパティ昇格」を活用しています。コンストラクタの引数に private のようなアクセス修飾子を付けると、プロパティの宣言と初期化が同時に行えコードが簡潔になります。この機能はPHP 8.0以降でなければ利用できない点に注意してください。また、FilterIteratorクラスを継承する場合は、親のコンストラクタ parent::__construct() を呼び出すことと、フィルタ条件を定義する accept() メソッドを必ず実装する必要があります。readonly修飾子(PHP 8.1以降)をプロパティに付けると、一度初期化されると再代入できなくなり、意図しない変更を防いでコードの安全性を高めます。
PHP 8 コンストラクタプロパティプロモーションでフィルタリングする
1<?php 2 3/** 4 * CallbackFilterIterator を継承し、 5 * PHP 8.0 のコンストラクタプロパティプロモーション機能を使用したカスタムイテレータクラス。 6 */ 7class EvenNumberFilter extends CallbackFilterIterator 8{ 9 /** 10 * コンストラクタ。 11 * 12 * 引数で public プロパティ $description を宣言し、同時に初期化します。 13 * これが「コンストラクタプロパティプロモーション」です。 14 * 15 * @param Iterator $iterator 反復処理するイテレータ 16 * @param callable $callback フィルタリングに使用するコールバック関数 17 * @param string $description このフィルタの説明 18 */ 19 public function __construct( 20 Iterator $iterator, 21 callable $callback, 22 public string $description // コンストラクタプロパティプロモーション 23 ) { 24 // 親クラスのコンストラクタを呼び出し、イテレータとコールバックをセットする 25 parent::__construct($iterator, $callback); 26 } 27} 28 29// 1. フィルタリング対象のデータとイテレータを用意する 30$numbers = new ArrayIterator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); 31 32// 2. フィルタリングのルールとなるコールバック関数を定義する (偶数のみ true) 33$evenCallback = fn(int $current): bool => $current % 2 === 0; 34 35// 3. コンストラクタプロパティプロモーションを使用したクラスのインスタンスを作成する 36$filter = new EvenNumberFilter( 37 $numbers, 38 $evenCallback, 39 'このイテレータは偶数のみを返します。' 40); 41 42// 4. コンストラクタでセットされたプロパティにアクセスする 43echo $filter->description . PHP_EOL; 44echo '--------------------------------' . PHP_EOL; 45 46// 5. フィルタリングされた結果を反復処理して出力する 47echo 'フィルタリング結果:' . PHP_EOL; 48foreach ($filter as $number) { 49 echo $number . PHP_EOL; 50} 51 52?>
このサンプルコードは、CallbackFilterIteratorクラスのコンストラクタ__constructを利用して、データの中から特定の条件に合う要素だけを抽出する方法を示しています。__constructは、オブジェクトが生成される際に一度だけ呼び出される初期化のためのメソッドです。
__constructは2つの引数を取ります。第一引数$iteratorには、フィルタリングしたいデータ群(この例では1から10の数値)を渡します。第二引数$callbackには、各要素をチェックするための「ルール」となる関数を渡します。このコールバック関数がtrueを返した要素だけが、最終的な結果として残ります。このサンプルでは、数値が偶数である場合にtrueを返す関数を定義しています。
また、このコードはPHP 8.0の新機能「コンストラクタプロパティプロモーション」も活用しています。EvenNumberFilterクラスのコンストラクタ引数でpublic string $descriptionと宣言することにより、プロパティの定義と初期化を同時に行い、コードを簡潔に記述できます。
__constructはオブジェクトの準備を行うメソッドであるため、戻り値はありません。最終的にforeachでフィルタオブジェクトを処理すると、コールバックのルールに従って偶数のみが抽出され、画面に出力されます。
PHP 8.0から導入されたコンストラクタプロパティプロモーションは、public string $description のように必ず可視性(public, protected, private)を記述する必要があります。可視性がないとプロパティとして宣言されません。また、CallbackFilterIterator のようなクラスを継承する場合、コンストラクタ内で parent::__construct() を呼び出し、親クラスに必要な引数を渡す処理を忘れずに行うことが重要です。これを怠るとフィルタ機能が正しく動作しません。第一引数には配列そのものではなく、サンプルの ArrayIterator のようなイテレータオブジェクトを渡してください。フィルタリングに使われるコールバック関数は、要素を残す場合は true、除外する場合は false を返すように実装する必要があります。