【PHP8.x】RecursiveRegexIterator::__construct()メソッドの使い方
__constructメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
__constructメソッドは、正規表現を用いて再帰イテレータをフィルタリングするRecursiveRegexIteratorの新しいインスタンスを生成するメソッドです。このメソッドは、ディレクトリ構造のような階層的なデータセットを扱う再帰イテレータを引数に取り、指定された正規表現パターンに一致する要素のみを処理対象とする新しいイテレータを作成します。第一引数には、フィルタリング対象となるRecursiveIteratorのインスタンスを渡します。第二引数には、要素を抽出するためのルールとなる正規表現パターンを文字列で指定します。さらに、オプションの引数で動作モードやフラグを細かく制御することが可能です。例えば、動作モードを指定することで、正規表現にマッチした要素全体を返すか、あるいはマッチした部分文字列だけを返すかといった挙動を選択できます。このコンストラクタを通じてインスタンスを生成することで、複雑なデータ構造の中から特定の条件に合致するデータのみを効率的に検索し、反復処理を行う準備が整います。
構文(syntax)
1new RecursiveRegexIterator( 2 RecursiveIterator $iterator, 3 string $pattern, 4 int $mode = RecursiveRegexIterator::MATCH, 5 int $flags = 0, 6 int $pregFlags = 0 7);
引数(parameters)
RecursiveIterator $iterator, string $pattern, int $mode = RecursiveRegexIterator::MATCH, int $flags = 0, int $pregFlags = 0
- RecursiveIterator $iterator: 再帰的に処理するイテレータを指定します。
- string $pattern: マッチさせる正規表現パターンを指定します。
- int $mode = RecursiveRegexIterator::MATCH: マッチモードを指定します。デフォルトは
RecursiveRegexIterator::MATCHです。 - int $flags = 0: イテレータのフラグを指定します。デフォルトは
0です。 - int $pregFlags = 0: 正規表現のフラグを指定します。デフォルトは
0です。
戻り値(return)
戻り値なし
戻り値はありません
サンプルコード
PHP 8 コンストラクタプロパティプロモーションによるフィルタリング処理
1<?php 2 3// RecursiveRegexIterator は SPL (Standard PHP Library) の一部です。 4// RecursiveIterator インターフェースを実装するクラスの例として、RecursiveArrayIterator を継承します。 5class MyArrayIterator extends RecursiveArrayIterator 6{ 7 public function __construct(array $array) 8 { 9 parent::__construct($array); 10 } 11} 12 13/** 14 * PHP 8 のコンストラクタプロパティプロモーションを使用して、 15 * RecursiveRegexIterator のようなフィルタリング処理に必要な引数を管理するクラスの例です。 16 * 17 * システムエンジニアを目指す初心者の方へ: 18 * プロパティプロモーションは、PHP 8で導入された非常に便利な機能です。 19 * 通常、コンストラクタで受け取った引数をクラスのプロパティに代入する記述が必要ですが、 20 * この機能を使うと、コンストラクタの引数宣言部分で直接プロパティとして宣言し、 21 * 初期化することができます。これにより、コードが簡潔になり、記述ミスも減らせます。 22 */ 23class FilterProcessor 24{ 25 // コンストラクタの引数宣言部分で public, protected, private のいずれかのアクセス修飾子を付けることで、 26 // その引数は自動的に同名のクラスプロパティとして定義され、コンストラクタが呼び出されたときに初期化されます。 27 public function __construct( 28 private RecursiveIterator $iterator, // 処理対象のイテレータ(データ源) 29 private string $pattern, // 適用する正規表現パターン 30 private int $mode = RecursiveRegexIterator::MATCH, // 正規表現のマッチングモード 31 private int $flags = 0, // 追加の動作を制御するフラグ (例: RecursiveRegexIterator::USE_KEY) 32 private int $pregFlags = 0 // PCRE正規表現エンジンに渡すフラグ (例: PREG_OFFSET_CAPTURE) 33 ) { 34 // コンストラクタの本体には、引数の追加の検証や複雑な初期化ロジックを記述できますが、 35 // この例ではプロパティプロモーションの動作を示すことが目的なので、特に処理はありません。 36 } 37 38 /** 39 * 設定された正規表現パターンとモードを使用してイテレータを処理し、 40 * マッチした結果を出力します。 41 */ 42 public function process(): void 43 { 44 echo "=== Processing with FilterProcessor ===\n"; 45 echo "Pattern: '{$this->pattern}'\n"; 46 echo "Mode: "; 47 // PHP 8 の 'match' 式を使って、モードを分かりやすい文字列に変換しています。 48 echo match ($this->mode) { 49 RecursiveRegexIterator::MATCH => 'MATCH (一致する要素を返す)', 50 RecursiveRegexIterator::GET_MATCH => 'GET_MATCH (一致する部分を配列で返す)', 51 RecursiveRegexIterator::ALL_MATCHES => 'ALL_MATCHES (全ての出現を配列で返す)', 52 RecursiveRegexIterator::REPLACE => 'REPLACE (置換は通常異なる方法で使用)', // この例では使用しません 53 default => 'UNKNOWN', 54 }; 55 echo "\n"; 56 echo "Flags: {$this->flags}, PregFlags: {$this->pregFlags}\n"; 57 echo "--------------------------------------\n"; 58 59 // プロパティプロモーションで定義されたプロパティを使用して、 60 // RecursiveRegexIterator のインスタンスを作成します。 61 $regexIterator = new RecursiveRegexIterator( 62 $this->iterator, 63 $this->pattern, 64 $this->mode, 65 $this->flags, 66 $this->pregFlags 67 ); 68 69 $hasMatches = false; 70 foreach ($regexIterator as $key => $value) { 71 $hasMatches = true; 72 echo " Key: {$key}, Value: "; 73 if (is_array($value)) { 74 // GET_MATCH や ALL_MATCHES モードの場合、値は配列になります。 75 echo "[" . implode(", ", array_map(function($v) { 76 return is_array($v) ? "['" . $v[0] . "' at " . $v[1] . "]" : "'" . $v . "'"; 77 }, $value)) . "]\n"; 78 } else { 79 echo "'{$value}'\n"; 80 } 81 } 82 83 if (!$hasMatches) { 84 echo " No matches found.\n"; 85 } 86 echo "=====================================\n\n"; 87 } 88} 89 90// --- サンプルデータの準備 --- 91$sampleData = [ 92 'fruit_apple' => 'red', 93 'fruit_banana' => 'yellow', 94 'vegetable_carrot' => 'orange', 95 'fruit_grape' => 'purple', 96 'vegetable_broccoli' => 'green', 97]; 98 99// MyArrayIterator のインスタンスを作成し、RecursiveIterator インターフェースを満たします。 100$myIterator = new MyArrayIterator($sampleData); 101 102// --- FilterProcessor の使用例 (プロパティプロモーションを活用) --- 103 104// 例1: キーが 'fruit' で始まる項目をマッチ (デフォルトモード: MATCH) 105$processor1 = new FilterProcessor( 106 $myIterator, 107 '/^fruit_/', // 'fruit_'で始まるキーにマッチ 108 RecursiveRegexIterator::MATCH, 109 RecursiveRegexIterator::USE_KEY // キーに対して正規表現を適用 110); 111$processor1->process(); 112 113// 例2: 値が 'orange' である項目を検索し、マッチした部分を取得 (GET_MATCHモード) 114$processor2 = new FilterProcessor( 115 $myIterator, 116 '/orange/', // 'orange'という文字列にマッチ 117 RecursiveRegexIterator::GET_MATCH, 118 RecursiveRegexIterator::USE_VALUES // 値に対して正規表現を適用 119); 120$processor2->process(); 121 122// 例3: キーまたは値に 'e' または 'a' が含まれる項目をマッチ (MATCHモード、複数フラグ) 123$processor3 = new FilterProcessor( 124 $myIterator, 125 '/[ea]/i', // 'e' または 'a' (大文字小文字を区別しない) にマッチ 126 RecursiveRegexIterator::MATCH, 127 RecursiveRegexIterator::USE_KEY | RecursiveRegexIterator::USE_VALUES // キーと値の両方に対して正規表現を適用 128); 129$processor3->process();
PHPのRecursiveRegexIteratorクラスの__constructメソッドは、イテレータ(データ集合を順に処理する仕組み)に対して正規表現によるフィルタリングを適用するために、その動作を初期設定する特別なメソッドです。システムエンジニアを目指す初心者の方へ、PHP 8で導入された「コンストラクタプロパティプロモーション」は、この初期設定をより簡潔に記述できる便利な機能です。通常、コンストラクタで受け取った引数をクラスのプロパティに代入する記述が必要ですが、プロパティプロモーションを使うと、コンストラクタの引数宣言部分でアクセス修飾子(public, privateなど)を付けるだけで、その引数を自動的にプロパティとして定義し、初期化できます。これにより、コードの記述量が減り、可読性が向上します。
サンプルコードのFilterProcessorクラスは、このプロパティプロモーションを活用し、RecursiveRegexIteratorのコンストラクタに必要な引数である$iterator、$pattern、$mode、$flags、$pregFlagsをプライベートプロパティとして宣言・初期化しています。具体的には、$iteratorはフィルタリング対象のデータ源、$patternは適用する正規表現、$modeはマッチング方法、$flagsは追加の動作を制御するフラグ、$pregFlagsは低レベルな正規表現エンジンに渡すフラグをそれぞれ表します。これにより、RecursiveRegexIteratorのインスタンスを生成する際にこれらのプロパティを再利用し、さまざまな条件でデータをフィルタリングする処理をシンプルに実現しています。この__constructメソッドは、クラスのインスタンスを生成するだけであり、特定の値を返すことはありません。
RecursiveRegexIteratorの__constructメソッドでは、第一引数に必ずRecursiveIteratorインターフェースを実装したオブジェクトを渡してください。第二引数の$patternは正規表現として正しく記述し、/pattern/のようにデリミタで囲む必要があります。誤った正規表現は実行時エラーの原因となります。また、$flags引数で正規表現をキーと値のどちらに適用するかを適切に指定しないと、期待するフィルタリング結果が得られないため注意が必要です。サンプルコードのFilterProcessorクラスで利用しているPHP 8のコンストラクタプロパティプロモーションは、コンストラクタ引数をプロパティとして自動定義・初期化する便利な機能です。これによりコードが簡潔になり、記述ミスも減らせるため、ぜひ活用を検討してください。
PHP RecursiveRegexIteratorのコンストラクタを拡張する
1<?php 2 3// テンポラリディレクトリを作成 4$tempDir = __DIR__ . '/temp_files'; 5if (!is_dir($tempDir)) { 6 mkdir($tempDir); 7} 8 9// テスト用のファイルをいくつか作成 10file_put_contents($tempDir . '/file1.txt', 'This is a text file.'); 11file_put_contents($tempDir . '/image.jpg', 'This is an image.'); 12file_put_contents($tempDir . '/document.docx', 'This is a document.'); 13file_put_contents($tempDir . '/another_file.txt', 'Another text file.'); 14file_put_contents($tempDir . '/sub/nested.txt', 'Nested text file.'); // サブディレクトリ 15 16/** 17 * RecursiveRegexIterator を継承したカスタムイテレータクラス。 18 * コンストラクタで親クラスのコンストラクタを呼び出す例を示す。 19 * 特定のパターンにマッチするファイルのみをフィルタリングします。 20 */ 21class MyFileFilterIterator extends RecursiveRegexIterator 22{ 23 /** 24 * コンストラクタ。 25 * 親クラス RecursiveRegexIterator のコンストラクタを呼び出します。 26 * 27 * @param RecursiveIterator $iterator 元となる再帰イテレータ。 28 * @param string $pattern フィルタリングに使う正規表現パターン。 29 * @param int $mode マッチングモード (RecursiveRegexIterator::MATCH など)。 30 * @param int $flags 追加のフラグ。 31 * @param int $pregFlags PCRE (Perl Compatible Regular Expressions) のフラグ。 32 */ 33 public function __construct( 34 RecursiveIterator $iterator, 35 string $pattern, 36 int $mode = RecursiveRegexIterator::MATCH, 37 int $flags = 0, 38 int $pregFlags = 0 39 ) { 40 // 親クラス RecursiveRegexIterator のコンストラクタを呼び出す 41 // これにより、基本的な正規表現フィルタリングの機能が初期化される 42 parent::__construct($iterator, $pattern, $mode, $flags, $pregFlags); 43 } 44} 45 46try { 47 // RecursiveDirectoryIterator を使用して、指定されたディレクトリを再帰的に走査するイテレータを作成 48 // FilesystemIterator::SKIP_DOTS は . と .. をスキップする 49 $directoryIterator = new RecursiveDirectoryIterator($tempDir, FilesystemIterator::SKIP_DOTS); 50 51 // MyFileFilterIterator をインスタンス化 52 // .txt 拡張子のファイルにマッチするパターンを指定 53 $regexIterator = new MyFileFilterIterator( 54 $directoryIterator, 55 '/^.+\.txt$/i' // 大文字小文字を区別しない .txt ファイル 56 ); 57 58 // RecursiveIteratorIterator を使用して、MyFileFilterIterator を再帰的にトラバース 59 echo "Filtering files with '.txt' extension:\n"; 60 foreach (new RecursiveIteratorIterator($regexIterator) as $file) { 61 echo " - " . $file->getPathname() . "\n"; 62 } 63 64} catch (Exception $e) { 65 echo "エラーが発生しました: " . $e->getMessage() . "\n"; 66} finally { 67 // テンポラリディレクトリとその中身をクリーンアップ 68 $iterator = new RecursiveIteratorIterator( 69 new RecursiveDirectoryIterator($tempDir, FilesystemIterator::SKIP_DOTS), 70 RecursiveIteratorIterator::CHILD_FIRST 71 ); 72 foreach ($iterator as $item) { 73 if ($item->isDir()) { 74 rmdir($item->getPathname()); 75 } else { 76 unlink($item->getPathname()); 77 } 78 } 79 rmdir($tempDir); 80 echo "\nTemporary directory '" . $tempDir . "' and its contents have been removed.\n"; 81} 82 83?>
PHPのRecursiveRegexIteratorは、ファイルやディレクトリなどを再帰的に走査しながら、正規表現に一致する要素だけをフィルタリングするためのクラスです。そのコンストラクタである__constructメソッドは、このフィルタリング機能を使うための初期設定を行います。
このコンストラクタには、以下の引数を指定します。
RecursiveIterator $iterator: フィルタリングの対象となる、元となるデータを提供するイテレータを指定します。string $pattern: フィルタリングに使用する正規表現のパターンを文字列で渡します。int $mode: 正規表現がマッチした要素をどのように扱うか(含めるか除外するかなど)を定義するモードを定数で指定します。int $flags: その他の動作を調整する追加のフラグを指定します。int $pregFlags: Perl互換正規表現(PCRE)エンジンの動作を微調整するフラグを指定します。 コンストラクタは新しいオブジェクトを初期化するだけで、特定の値を戻り値として返しません。
サンプルコードでは、RecursiveRegexIteratorを継承してMyFileFilterIteratorというカスタムクラスを作成しています。このMyFileFilterIteratorクラスのコンストラクタ内でparent::__construct()を呼び出すことにより、親クラスであるRecursiveRegexIteratorの初期化処理を明示的に実行しています。これにより、MyFileFilterIteratorは、親クラスが持つ正規表現によるフィルタリング機能を正しく利用できるようになります。この例では、.txt拡張子を持つファイルのみを効果的に抽出して表示しています。
このサンプルコードでは、RecursiveRegexIteratorを継承する際、カスタムクラスのコンストラクタ内でparent::__constructを呼び出すことが特に重要です。この呼び出しを省略すると、親クラスの基本的な正規表現フィルタリング機能が初期化されず、エラーや予期せぬ動作の原因となりますので注意が必要です。親クラスのコンストラクタへ渡す引数は、型と順序を正しく引き継いでください。また、RecursiveDirectoryIteratorとRecursiveRegexIterator、RecursiveIteratorIteratorを組み合わせて、ディレクトリの走査、フィルタリング、再帰的な処理を実現するイテレータの連携構造を理解することは、ファイル処理を効率的に行う上で役立ちます。一時的なファイルやディレクトリを作成する際は、finallyブロックを利用して、エラー発生時も含め必ずクリーンアップする処理を記述し、リソースの解放を徹底することが、堅牢なシステムを構築する上で不可欠です。