【PHP8.x】RecursiveFilterIterator::__construct()メソッドの使い方
__constructメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
『__constructメソッドは、RecursiveFilterIteratorの新しいインスタンスを生成するメソッドです』
このメソッドは、フィルタリングの対象となる、RecursiveIteratorインターフェースを実装したイテレータを引数として受け取り、インスタンスを初期化する役割を担います。RecursiveFilterIteratorは、木構造のような再帰的なデータ構造を走査する際に、特定の条件に合致する要素だけを抽出するために使用されます。ただし、RecursiveFilterIteratorは抽象クラスであるため、new RecursiveFilterIterator()のように直接インスタンスを生成することはできません。このクラスを利用するには、まずこれを継承した独自のフィルタクラスを作成する必要があります。そして、その独自クラスのコンストラクタ内から parent::__construct() を呼び出し、フィルタリングしたいイテレータを渡すことで初期化を行います。また、継承したクラスでは、要素をフィルタリングする具体的な条件を定義する accept() メソッドを必ず実装しなければなりません。
構文(syntax)
1public __construct(RecursiveIterator $iterator)
引数(parameters)
RecursiveIterator $iterator
- RecursiveIterator $iterator: フィルタリング対象となるRecursiveIteratorインスタンス
戻り値(return)
戻り値なし
戻り値はありません
サンプルコード
PHP RecursiveFilterIteratorのコンストラクタでフィルタリングする
1<?php 2 3/** 4 * RecursiveFilterIteratorを継承し、PHPファイルのみを抽出するカスタムフィルタクラス 5 * 6 * RecursiveFilterIteratorは抽象クラスのため、直接インスタンス化できません。 7 * このように継承した具象クラスを作成して利用します。 8 */ 9class PhpFileFilterIterator extends RecursiveFilterIterator 10{ 11 /** 12 * コンストラクタ 13 * 14 * キーワード「php class constructor」の例として、このメソッドが呼び出されます。 15 * 親クラスである RecursiveFilterIterator のコンストラクタに、 16 * 引数で受け取ったイテレータを渡します。 17 * 18 * @param RecursiveIterator $iterator フィルタリング対象のイテレータ 19 */ 20 public function __construct(RecursiveIterator $iterator) 21 { 22 // 親クラスのコンストラクタを呼び出す 23 parent::__construct($iterator); 24 } 25 26 /** 27 * フィルタリング条件を定義するメソッド 28 * 29 * このメソッドが true を返したアイテムのみが結果に含まれます。 30 * 31 * @return bool アイテムを結果に含める場合は true、含めない場合は false 32 */ 33 public function accept(): bool 34 { 35 // 現在のアイテムがファイルであり、かつ拡張子が 'php' の場合に true を返す 36 return $this->current()->isFile() && $this->current()->getExtension() === 'php'; 37 } 38} 39 40// --- 以下、動作確認用のコード --- 41 42// テスト用のディレクトリとファイル構造を一時的に作成 43$testDir = 'temp_test_dir_for_iterator'; 44if (!is_dir($testDir)) { 45 mkdir($testDir . '/subdir', 0777, true); 46} 47touch($testDir . '/index.php'); 48touch($testDir . '/style.css'); 49touch($testDir . '/subdir/app.php'); 50touch($testDir . '/subdir/script.js'); 51 52echo "拡張子が.phpのファイルのみを再帰的に検索します:\n"; 53 54try { 55 // 1. ディレクトリを再帰的に走査するイテレータを準備 56 $dirIterator = new RecursiveDirectoryIterator( 57 $testDir, 58 FilesystemIterator::SKIP_DOTS 59 ); 60 61 // 2. カスタムフィルタクラスのコンストラクタにイテレータを渡してインスタンス化 62 $phpFileFilter = new PhpFileFilterIterator($dirIterator); 63 64 // 3. フィルタリングされた結果をたどるためのイテレータを準備 65 $iterator = new RecursiveIteratorIterator($phpFileFilter); 66 67 // 4. 結果をループして表示 68 foreach ($iterator as $file) { 69 echo $file->getPathname() . "\n"; 70 } 71} finally { 72 // 後片付け: 作成した一時ディレクトリとファイルを削除 73 unlink($testDir . '/subdir/script.js'); 74 unlink($testDir . '/subdir/app.php'); 75 rmdir($testDir . '/subdir'); 76 unlink($testDir . '/style.css'); 77 unlink($testDir . '/index.php'); 78 rmdir($testDir); 79}
RecursiveFilterIteratorクラスのコンストラクタ__constructは、フィルタ機能を持つ特殊なイテレータ(繰り返し処理を行うオブジェクト)を生成する際に呼び出される初期化メソッドです。
このRecursiveFilterIteratorは、それ自体を直接インスタンス化できない「抽象クラス」です。そのため、利用する際にはサンプルコードのPhpFileFilterIteratorのように、このクラスを継承した具象クラスを自分で定義する必要があります。
コンストラクタの引数$iteratorには、フィルタリングしたい対象のデータを持つRecursiveIteratorオブジェクトを渡します。サンプルコードでは、特定のディレクトリ内を再帰的に走査するRecursiveDirectoryIteratorのインスタンスがこれに該当します。
継承したクラスのコンストラクタ内では、parent::__construct($iterator)という形式で親クラスのコンストラクタを呼び出します。これにより、引数で受け取ったイテレータがフィルタリングの対象として内部に設定され、オブジェクトが利用可能な状態に初期化されます。コンストラクタはオブジェクトの初期化を目的とするため、特定の戻り値はありません。
__constructは、クラスからオブジェクトを生成する際に自動的に呼び出される特別なメソッド(コンストラクタ)です。クラスを継承してコンストラクタを定義する場合、parent::__construct() を使って親クラスの初期化処理を呼び出すことが重要です。これを忘れると、親クラスが持つ機能が正しく動作しない原因となります。また、RecursiveFilterIteratorのような抽象クラスは直接インスタンス化できません。サンプルコードのように、必ず継承したクラスを作成し、フィルタリングの条件を定義するacceptメソッドを実装する必要があります。引数にRecursiveIteratorのような型を指定することで、意図しないデータが渡されるのを防ぎ、コードの安全性を高めることができます。
RecursiveFilterIteratorのコンストラクタでフィルタリングする
1<?php 2 3/** 4 * 'a'で始まる文字列のみを許可するカスタムフィルタクラス。 5 * 6 * RecursiveFilterIteratorを継承して、特定の条件で要素をフィルタリングします。 7 */ 8class StartsWithAFilter extends RecursiveFilterIterator 9{ 10 /** 11 * コンストラクタ: フィルタリング対象のイテレータを受け取ります。 12 * 13 * このコンストラクタは、PHPがクラスの新しいインスタンスを作成するときに自動的に呼び出されます。 14 * ここでは、親クラスである RecursiveFilterIterator のコンストラクタに、 15 * フィルタをかけたいイテレータ($iterator)を渡しています。 16 * 17 * @param RecursiveIterator $iterator フィルタリング対象のイテレータ 18 */ 19 public function __construct(RecursiveIterator $iterator) 20 { 21 parent::__construct($iterator); 22 } 23 24 /** 25 * フィルタリングの条件を定義するメソッド。 26 * 27 * @return bool この要素をイテレーションに含める場合は true、除外する場合は false を返します。 28 */ 29 public function accept(): bool 30 { 31 // 現在の要素が文字列で、かつ先頭が 'a' で始まる場合のみ true を返します。 32 $current = $this->current(); 33 return is_string($current) && str_starts_with($current, 'a'); 34 } 35} 36 37// フィルタリングの対象となる多次元配列データ 38$data = [ 39 'fruits' => ['apple', 'banana', 'avocado'], 40 'vegetables' => [ 41 'green' => ['spinach', 'broccoli'], 42 'red' => 'tomato' 43 ], 44 'other' => 'animal', 45]; 46 47// 1. 配列を再帰的に走査するためのイテレータを作成 48$arrayIterator = new RecursiveArrayIterator($data); 49 50// 2. カスタムフィルタクラスをインスタンス化 51// このとき、コンストラクタ (__construct) に $arrayIterator を渡します。 52$filterIterator = new StartsWithAFilter($arrayIterator); 53 54// 3. フィルタリングされた結果を再帰的に走査するためのイテレータを作成 55$recursiveIterator = new RecursiveIteratorIterator($filterIterator); 56 57// 4. フィルタリング後の結果をループして表示 58// 期待される出力: apple, avocado, animal 59echo "--- 'a'で始まる要素のみ表示 ---" . PHP_EOL; 60foreach ($recursiveIterator as $value) { 61 echo $value . PHP_EOL; 62} 63 64?>
RecursiveFilterIteratorの__constructメソッドは、クラスのインスタンスを生成する際に自動的に呼び出される特別なメソッドで、PHPでは「コンストラクタ」と呼ばれます。このメソッドの主な役割は、フィルタリング機能を持つオブジェクトを正しく使えるように初期設定を行うことです。
引数には、フィルタリングの対象となるRecursiveIteratorオブジェクトを一つ受け取ります。これにより、どのデータを走査して条件に合うものだけを残すかを指定します。戻り値はありません。これは、メソッドの目的が値を返すことではなく、オブジェクト内部の状態を準備することにあるためです。
サンプルコードでは、RecursiveFilterIteratorを継承したStartsWithAFilterクラスを作成しています。new StartsWithAFilter($arrayIterator)の部分でインスタンスが生成されると、このコンストラクタが実行されます。引数として渡された$arrayIterator(多次元配列のデータ)は、parent::__construct($iterator)という記述を通じて親クラスに渡されます。この処理によって、フィルタリング対象のデータがオブジェクトに設定され、後からacceptメソッドで定義された条件に基づいて要素を絞り込めるようになります。
__constructは、クラスから新しいインスタンスを作成する際に自動で呼び出される初期化用のメソッドです。このサンプルコードのように、別のクラスを継承して独自のコンストラクタを定義した場合、parent::__construct()を呼び出して親クラスの初期化処理を明示的に行うことが非常に重要です。これを忘れると、フィルタ対象のイテレータが正しくセットされず、クラスが期待通りに動作しない原因となります。また、コンストラクタの引数にはRecursiveIteratorという型が指定されているため、このルールに合ったオブジェクト(例:RecursiveArrayIteratorのインスタンス)を渡す必要があります。間違った型の値を渡すとエラーになるため注意してください。