【PHP8.x】RecursiveDirectoryIterator::setInfoClass()メソッドの使い方
setInfoClassメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
setInfoClassメソッドは、RecursiveDirectoryIteratorが、ディレクトリ内の各ファイルやディレクトリの情報をどのようなオブジェクトとして提供するかを設定するメソッドです。
RecursiveDirectoryIteratorは、指定されたディレクトリとその配下のサブディレクトリを再帰的に探索し、ファイルやディレクトリを順に処理するための機能を提供します。通常、このイテレータが各要素の情報として返すのは、PHPに標準で備わっているSplFileInfoクラスのオブジェクトです。
しかし、開発者がファイルやディレクトリに関する標準情報に加えて、独自の処理や追加のプロパティを組み込みたい場合があります。そのような場合、SplFileInfoを継承した独自の情報クラス(カスタムクラス)を作成できます。setInfoClassメソッドを使うことで、このカスタムクラスをRecursiveDirectoryIteratorに設定し、イテレータが返す情報オブジェクトが、標準のSplFileInfoではなく、開発者が定義したカスタムクラスのインスタンスとして返されるように変更できます。これにより、例えば、ファイルの種類に応じた専用の操作メソッドを追加したり、特定の情報を事前に整形しておくなど、より柔軟で高度なファイルシステム操作を実現できます。
構文(syntax)
1<?php 2 3// SplFileInfo を継承したカスタムクラスを定義します。 4// RecursiveDirectoryIterator はこのクラスのインスタンスをファイル情報として返します。 5class MyFileInfo extends SplFileInfo {} 6 7// RecursiveDirectoryIterator のインスタンスを作成します。 8// ここでは例として '/path/to/directory' を指定していますが、実際のディレクトリパスに置き換えてください。 9$iterator = new RecursiveDirectoryIterator('/path/to/directory'); 10 11// setInfoClass メソッドを使って、イテレータが使用するファイル情報クラスを 12// 定義した MyFileInfo クラスに変更します。 13// MyFileInfo::class は PHP 5.5 以降で推奨される、クラス名を文字列として取得する方法です。 14$iterator->setInfoClass(MyFileInfo::class);
引数(parameters)
string $class = RecursiveDirectoryIterator::class
- string $class = RecursiveDirectoryIterator::class: ファイル情報を保持するクラス名を指定する文字列。デフォルトでは RecursiveDirectoryIterator::class が使用される。
戻り値(return)
戻り値なし
戻り値はありません
サンプルコード
PHP RecursiveDirectoryIterator でカスタムクラスを取得する
1<?php 2 3/** 4 * SplFileInfo を継承したカスタムクラス。 5 * RecursiveDirectoryIterator が返すファイル情報オブジェクトをこのクラスのインスタンスにする例。 6 */ 7class MyFileInfo extends SplFileInfo 8{ 9 /** 10 * ファイルパスにカスタム文字列を追加したものを返します。 11 * @return string カスタムフォーマットされたファイルパス 12 */ 13 public function getCustomPathname(): string 14 { 15 return 'CUSTOM_PREFIX: ' . $this->getPathname(); 16 } 17} 18 19/** 20 * RecursiveDirectoryIterator と setInfoClass を使用してディレクトリを走査する例。 21 * setInfoClass でカスタムの SplFileInfo クラスを設定し、返されるオブジェクトのクラスを確認します。 22 */ 23function exploreDirectoryWithCustomFileInfo(): void 24{ 25 // 一時ディレクトリの名前を定義 26 $testDir = __DIR__ . '/temp_recursive_dir_test'; 27 28 try { 29 // テスト用のディレクトリとファイルを準備 30 if (!is_dir($testDir)) { 31 mkdir($testDir, 0777, true); 32 } 33 file_put_contents($testDir . '/file1.txt', 'Test content for file1.'); 34 mkdir($testDir . '/subdir', 0777, true); 35 file_put_contents($testDir . '/subdir/file2.txt', 'Test content for file2.'); 36 37 echo "テストディレクトリ '" . realpath($testDir) . "' を作成しました。\n\n"; 38 39 // RecursiveDirectoryIterator のインスタンスを作成 40 $directoryIterator = new RecursiveDirectoryIterator( 41 $testDir, 42 RecursiveDirectoryIterator::SKIP_DOTS // ドットエントリ ('.' と '..') をスキップ 43 ); 44 45 // setInfoClass メソッドを使って、SplFileInfo の代わりにカスタムクラス (MyFileInfo) を設定します。 46 // これにより、イテレータが返す各ファイル/ディレクトリ情報オブジェクトが MyFileInfo のインスタンスになります。 47 $directoryIterator->setInfoClass(MyFileInfo::class); 48 echo "RecursiveDirectoryIterator に MyFileInfo クラスを設定しました。\n\n"; 49 50 // RecursiveIteratorIterator を使ってディレクトリを再帰的に走査 51 $iterator = new RecursiveIteratorIterator($directoryIterator); 52 53 echo "ディレクトリを走査中...\n"; 54 foreach ($iterator as $name => $info) { 55 // オブジェクトのクラス名を取得し、設定したカスタムクラスが適用されているか確認します。 56 // (キーワード: php get class) 57 $className = get_class($info); 58 59 echo "----------------------------------------\n"; 60 echo "名前: " . $name . "\n"; 61 echo "パス: " . $info->getPathname() . "\n"; 62 echo "取得されたオブジェクトのクラス: " . $className . "\n"; 63 64 // オブジェクトが MyFileInfo のインスタンスであることを確認し、カスタムメソッドを呼び出します。 65 if ($info instanceof MyFileInfo) { 66 echo "MyFileInfo のカスタムパス: " . $info->getCustomPathname() . "\n"; 67 } else { 68 echo "エラー: オブジェクトが MyFileInfo のインスタンスではありませんでした。\n"; 69 } 70 } 71 echo "----------------------------------------\n"; 72 echo "\n走査が完了しました。\n"; 73 74 } catch (Exception $e) { 75 echo "エラーが発生しました: " . $e->getMessage() . "\n"; 76 } finally { 77 // テスト用のディレクトリとファイルをクリーンアップ 78 if (is_dir($testDir)) { 79 $files = new RecursiveIteratorIterator( 80 new RecursiveDirectoryIterator($testDir, RecursiveDirectoryIterator::SKIP_DOTS), 81 RecursiveIteratorIterator::CHILD_FIRST 82 ); 83 foreach ($files as $fileinfo) { 84 if ($fileinfo->isDir()) { 85 rmdir($fileinfo->getRealPath()); 86 } else { 87 unlink($fileinfo->getRealPath()); 88 } 89 } 90 rmdir($testDir); 91 echo "\nテストディレクトリ '" . $testDir . "' をクリーンアップしました。\n"; 92 } 93 } 94} 95 96// サンプルコードの実行 97exploreDirectoryWithCustomFileInfo(); 98 99?>
RecursiveDirectoryIterator::setInfoClassは、PHPでディレクトリを再帰的に走査する際に、各ファイルやディレクトリの情報を表すオブジェクトのクラスを指定するためのメソッドです。通常、この情報は標準のSplFileInfoクラスのインスタンスとして提供されますが、このメソッドを使用すると、SplFileInfoを継承した独自のカスタムクラスを設定できます。
引数$classには、ファイル情報オブジェクトとして使用したいカスタムクラスの完全修飾名を文字列で渡します。このカスタムクラスは必ずSplFileInfoを継承している必要があります。このメソッド自体は値を返しません。
サンプルコードでは、MyFileInfoというSplFileInfoを継承したカスタムクラスを定義し、その中にgetCustomPathnameという独自のメソッドを追加しています。RecursiveDirectoryIteratorのインスタンスに対してsetInfoClass(MyFileInfo::class)を呼び出すことで、イテレータが返す各ファイル/ディレクトリ情報オブジェクトがMyFileInfoのインスタンスになるよう設定しています。実際にディレクトリを走査するループ内で、get_class($info)関数を使って取得されたオブジェクトのクラス名を確認し、MyFileInfoが適用されていることと、そのカスタムメソッドが利用できることを示しています。これにより、ファイル情報に独自の機能や処理を追加できるため、より柔軟なファイル操作が可能になります。
setInfoClassメソッドを使用する際は、引数に指定するカスタムクラスが必ずSplFileInfoを継承している必要があります。これにより、RecursiveDirectoryIteratorが返すオブジェクトがSplFileInfo本来の機能に加え、カスタムクラスで定義したメソッドも利用可能になります。引数にはクラス名を文字列で渡しますが、MyClass::classのようにクラス定数を使うと、タイプミスを防ぎつつコードの可読性も向上します。
このメソッド自体は設定を行うだけで戻り値がないため、設定後にイテレータから取得されるオブジェクトが、期待通りカスタムクラスのインスタンスになっているか、get_class()関数やinstanceof演算子で確認すると良いでしょう。また、サンプルコードのようにテスト目的で一時的なディレクトリやファイルを作成した場合は、処理の最後にfinallyブロックを利用して、確実にクリーンアップ処理を行うことが重要です。これにより、意図しないファイルがシステムに残るのを防ぎ、安全にコードを運用できます。
PHP: RecursiveDirectoryIteratorでクラス名設定
1<?php 2 3/** 4 * SplFileInfo を継承するカスタムクラスを定義します。 5 * RecursiveDirectoryIterator::setInfoClass() メソッドで使用されます。 6 */ 7class MyFileInfo extends SplFileInfo 8{ 9 /** 10 * カスタムクラスに独自のメソッドを追加できます。 11 * このメソッドは、ファイルまたはディレクトリに関する追加情報を提供します。 12 * 13 * @return string ファイルまたはディレクトリのカスタム情報 14 */ 15 public function getMyCustomInfo(): string 16 { 17 return "カスタム情報: " . $this->getFilename() . " (" . $this->getType() . ")"; 18 } 19} 20 21/** 22 * RecursiveDirectoryIterator を使用してディレクトリを走査し、 23 * setInfoClass() メソッドでカスタムクラスを設定する例。 24 * 25 * このコードは、スクリプトが実行されている現在のディレクトリを対象とします。 26 */ 27try { 28 // 1. 走査対象のディレクトリを指定します。 29 // ここでは、このスクリプトが存在するディレクトリ(__DIR__) を対象とします。 30 $targetDirectory = __DIR__; 31 32 // 2. RecursiveDirectoryIterator のインスタンスを作成します。 33 // FilesystemIterator::SKIP_DOTS フラグは、"." と ".." ディレクトリをスキップします。 34 $directoryIterator = new RecursiveDirectoryIterator( 35 $targetDirectory, 36 FilesystemIterator::SKIP_DOTS 37 ); 38 39 // 3. setInfoClass() メソッドを使用して、イテレータが返すオブジェクトのクラスを設定します。 40 // デフォルトでは SplFileInfo クラスのインスタンスを返しますが、 41 // ここでは MyFileInfo::class を指定することで、MyFileInfo のインスタンスを返すようになります。 42 $directoryIterator->setInfoClass(MyFileInfo::class); 43 44 // 4. RecursiveIteratorIterator のインスタンスを作成し、ディレクトリを再帰的に走査します。 45 $iterator = new RecursiveIteratorIterator($directoryIterator); 46 47 echo "ディレクトリの内容をカスタムクラス (MyFileInfo) で表示:\n"; 48 49 // 5. 各ファイルまたはディレクトリをループ処理します。 50 foreach ($iterator as $file) { 51 // 返されるオブジェクトのクラス名を取得し、表示します。 52 // setInfoClass() で設定した MyFileInfo クラスになっていることを確認できます。 53 echo " ファイル/ディレクトリ名: " . $file->getFilename() . "\n"; 54 echo " オブジェクトのクラス: " . get_class($file) . "\n"; 55 56 // オブジェクトが MyFileInfo のインスタンスであることを確認し、 57 // カスタムメソッドを利用します。 58 if ($file instanceof MyFileInfo) { 59 echo " " . $file->getMyCustomInfo() . "\n"; 60 } 61 echo "\n"; 62 } 63} catch (UnexpectedValueException $e) { 64 // 指定されたパスが存在しない、またはディレクトリでない場合に発生するエラー 65 echo "エラー: 指定されたパスが無効です - " . $e->getMessage() . "\n"; 66} catch (Exception $e) { 67 // その他の予期せぬエラー 68 echo "予期せぬエラーが発生しました: " . $e->getMessage() . "\n"; 69}
RecursiveDirectoryIterator::setInfoClass()メソッドは、PHPでディレクトリを再帰的に走査する際に、ファイルやディレクトリの情報を取得するオブジェクトのクラスを変更するための機能です。通常、このイテレータはSplFileInfoクラスのインスタンスを返しますが、setInfoClass()を使用することで、SplFileInfoを継承した独自のカスタムクラスのインスタンスを返すように設定できます。
引数$classには、SplFileInfoを継承したカスタムクラスの完全なクラス名を文字列で指定します。これにより、カスタムクラスに追加した独自のメソッドやプロパティを、ディレクトリ走査の結果として得られるオブジェクトで利用できるようになります。このメソッド自体は値を返しませんが、イテレータが返すオブジェクトの型を設定する効果を持ちます。
サンプルコードでは、SplFileInfoを継承したMyFileInfoというカスタムクラスを定義し、getMyCustomInfo()という独自のメソッドを追加しています。RecursiveDirectoryIteratorのインスタンスを作成した後、setInfoClass(MyFileInfo::class)を呼び出すことで、ディレクトリ走査中に取得される各ファイルやディレクトリの情報がMyFileInfoのインスタンスとして返されるよう設定しています。
結果として、ループ内で取得される$fileオブジェクトはMyFileInfoのインスタンスとなり、get_class($file)でそのクラス名を確認したり、$file->getMyCustomInfo()のようにカスタムクラスで定義したメソッドを安全に呼び出して独自の情報を表示することが可能になります。これにより、ファイルシステムの情報処理に柔軟性を持たせ、特定の用途に合わせたカスタムデータを含めることができます。エラーが発生した場合は、適切な例外処理が行われます。
setInfoClass()は、ファイルやディレクトリ情報を扱うオブジェクトを、開発者が定義したカスタムクラスに切り替えるメソッドです。カスタムクラスは必ずSplFileInfoを継承してください。これにより、既存のファイル情報メソッドを維持しつつ、getMyCustomInfo()のような独自のメソッドを追加して、より柔軟な処理を行えるようになります。クラス指定にはMyFileInfo::classのようにクラス定数を使用すると、タイプミスを防ぎ、可読性も向上します。ループ内でカスタムメソッドを利用する際は、instanceofでオブジェクトがカスタムクラスであることを確認してから呼び出すと、予期せぬエラーを防ぎ、より安全なコードになります。