【PHP8.x】RecursiveDirectoryIterator::current()メソッドの使い方
currentメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
currentメソッドは、RecursiveDirectoryIteratorが現在指している要素を取得するメソッドです。RecursiveDirectoryIteratorは、指定されたディレクトリとそのサブディレクトリを再帰的に走査するための特別なイテレータです。このcurrentメソッドは、イテレータが順次たどっていくファイルやディレクトリの中から、「今、処理の対象となっている」要素の情報を取得する役割を担います。
このメソッドの戻り値は、SplFileInfoクラスのオブジェクトです。SplFileInfoオブジェクトは、取得した要素に関する詳細な情報、例えばファイルやディレクトリのパス、名前、サイズ、最終更新日時、ファイルの種類(それがファイルであるかディレクトリであるかなど)をカプセル化して提供します。これにより、開発者はファイルシステムの各要素に対して、安全かつ効率的に様々な操作を行うことが可能になります。主に、foreachループなどでディレクトリ構造を走査し、各要素に対して特定の処理を実行する際に利用され、ファイルシステム操作の基盤となる非常に重要なメソッドです。
構文(syntax)
1<?php 2$iterator = new RecursiveDirectoryIterator('./'); 3$fileInfoObject = $iterator->current(); 4?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
SplFileInfo
現在イテレーションしているディレクトリ内のファイルまたはサブディレクトリを表す SplFileInfo オブジェクトを返します。
サンプルコード
RecursiveDirectoryIterator::current() でディレクトリ項目を取得する
1<?php 2 3/** 4 * RecursiveDirectoryIterator::current() メソッドの使用例を示します。 5 * 6 * この関数は、一時的なディレクトリ構造を作成し、RecursiveDirectoryIterator を用いて 7 * その中を再帰的に走査します。走査中に RecursiveDirectoryIterator::current() を呼び出し、 8 * 現在処理中のファイルまたはディレクトリに関する SplFileInfo オブジェクトの情報を表示します。 9 * 10 * @param string $basePath デモンストレーション用の一時ディレクトリを作成するベースパス 11 * @return void 12 */ 13function demonstrateRecursiveDirectoryIteratorCurrent(string $basePath): void 14{ 15 // 1. デモンストレーション用の一時ディレクトリとファイルを作成します 16 $tempDir = $basePath . DIRECTORY_SEPARATOR . 'demo_dir_' . uniqid(); 17 if (!mkdir($tempDir, 0777, true)) { 18 echo "エラー: 一時ディレクトリ '{$tempDir}' の作成に失敗しました。" . PHP_EOL; 19 return; 20 } 21 mkdir($tempDir . DIRECTORY_SEPARATOR . 'subdir_a', 0777, true); 22 mkdir($tempDir . DIRECTORY_SEPARATOR . 'subdir_b', 0777, true); 23 file_put_contents($tempDir . DIRECTORY_SEPARATOR . 'file_1.txt', 'Content 1'); 24 file_put_contents($tempDir . DIRECTORY_SEPARATOR . 'subdir_a' . DIRECTORY_SEPARATOR . 'file_2.log', 'Log entry'); 25 file_put_contents($tempDir . DIRECTORY_SEPARATOR . 'subdir_b' . DIRECTORY_SEPARATOR . 'file_3.json', '{"key": "value"}'); 26 27 echo "--- ディレクトリ走査開始: {$tempDir} ---" . PHP_EOL; 28 29 try { 30 // 2. RecursiveDirectoryIterator をインスタンス化します 31 // FilesystemIterator::SKIP_DOTS フラグで '.' と '..' エントリをスキップします。 32 $directoryIterator = new RecursiveDirectoryIterator( 33 $tempDir, 34 FilesystemIterator::SKIP_DOTS 35 ); 36 37 // 3. RecursiveIteratorIterator で RecursiveDirectoryIterator をラップし、 38 // ディレクトリ構造を再帰的に走査できるようにします。 39 // RecursiveIteratorIterator::SELF_FIRST は、ディレクトリ自身を先に走査し、 40 // 次にその中の項目を走査するよう指定します。 41 $recursiveIterator = new RecursiveIteratorIterator( 42 $directoryIterator, 43 RecursiveIteratorIterator::SELF_FIRST 44 ); 45 46 // イテレータを最初の項目に設定します 47 $recursiveIterator->rewind(); 48 49 // 4. ディレクトリ内のすべてのファイルとサブディレクトリを走査します 50 while ($recursiveIterator->valid()) { 51 // RecursiveIteratorIterator から現在の RecursiveDirectoryIterator インスタンスを取得します。 52 // RecursiveDirectoryIterator::current() を呼び出すには、この内部イテレータが必要です。 53 $currentRecursiveDirectoryIterator = $recursiveIterator->getInnerIterator(); 54 55 // RecursiveDirectoryIterator::current() を呼び出し、 56 // 現在の項目を表す SplFileInfo オブジェクトを取得します。 57 $fileInfo = $currentRecursiveDirectoryIterator->current(); 58 59 // 取得した SplFileInfo オブジェクトのプロパティを表示して、 60 // current() メソッドの戻り値を示します。 61 echo "現在の項目情報:" . PHP_EOL; 62 echo " パス: " . $fileInfo->getPathname() . PHP_EOL; 63 echo " 名前: " . $fileInfo->getFilename() . PHP_EOL; 64 echo " 種類: " . ($fileInfo->isDir() ? "ディレクトリ" : "ファイル") . PHP_EOL; 65 if ($fileInfo->isFile()) { 66 echo " サイズ: " . $fileInfo->getSize() . " バイト" . PHP_EOL; 67 } 68 echo "-----------------------------------" . PHP_EOL; 69 70 // 次の項目へ進みます 71 $recursiveIterator->next(); 72 } 73 } catch (UnexpectedValueException $e) { 74 echo "エラー: ディレクトリの読み込み中に問題が発生しました: " . $e->getMessage() . PHP_EOL; 75 } catch (RuntimeException $e) { 76 echo "エラー: ランタイムエラーが発生しました: " . $e->getMessage() . PHP_EOL; 77 } 78 79 echo "--- ディレクトリ走査終了 ---" . PHP_EOL; 80 81 // 5. 後処理: 作成した一時ディレクトリとファイルを削除します 82 // RecursiveIteratorIterator::CHILD_FIRST を使用して、子要素を先に削除します。 83 $cleanupIterator = new RecursiveIteratorIterator( 84 new RecursiveDirectoryIterator($tempDir, FilesystemIterator::SKIP_DOTS), 85 RecursiveIteratorIterator::CHILD_FIRST 86 ); 87 foreach ($cleanupIterator as $file) { 88 /** @var SplFileInfo $file */ 89 if ($file->isDir()) { 90 rmdir($file->getPathname()); 91 } elseif ($file->isFile()) { 92 unlink($file->getPathname()); 93 } 94 } 95 rmdir($tempDir); 96 echo "一時ディレクトリ '{$tempDir}' をクリーンアップしました。" . PHP_EOL; 97} 98 99// スクリプトが実行されているカレントディレクトリをベースパスとして使用します 100demonstrateRecursiveDirectoryIteratorCurrent(__DIR__); 101
このサンプルコードは、PHPのRecursiveDirectoryIteratorクラスにおけるcurrent()メソッドの具体的な使用方法を示しています。このメソッドは引数を必要とせず、RecursiveDirectoryIteratorが現在指し示しているファイルまたはディレクトリに関する詳細情報を提供するSplFileInfoオブジェクトを返します。
コードではまず、デモンストレーション用に一時的なディレクトリと複数のファイルを準備します。次に、RecursiveDirectoryIteratorと、それを再帰的に扱えるようにするRecursiveIteratorIteratorを組み合わせて、作成したディレクトリ構造全体を走査します。走査の各ステップでRecursiveDirectoryIterator::current()が呼び出され、現在処理中のファイルやサブディレクトリに関するSplFileInfoオブジェクトを取得します。取得したSplFileInfoオブジェクトから、項目のパス、ファイル名、種類、ファイルサイズといったさまざまな情報を抽出し、画面に表示しています。
SplFileInfoオブジェクトは、ファイルシステムの項目に特化した情報を一元的に管理し、それらの情報へ簡単にアクセスできる便利なインターフェースを提供します。このように、current()メソッドは、ディレクトリを再帰的に探索しながら、各項目に対して具体的な操作や情報取得を行う際に中心的な役割を果たします。最後に、作成した一時ディレクトリとファイルをすべて削除し、クリーンアップを行っています。
このサンプルコードでは、RecursiveIteratorIterator を用いてディレクトリを再帰的に走査する際、RecursiveDirectoryIterator::current() メソッドを呼び出すために $recursiveIterator->getInnerIterator() を介して内部のイテレータを取得しています。これにより、現在処理中の項目について正確な SplFileInfo オブジェクトを受け取ることができ、ファイル名やパス、種類などの情報を安全に取得・利用できます。current() の戻り値が SplFileInfo であるため、統一的な方法でファイル情報を扱える点が重要です。ファイルシステム操作は権限やパス指定の誤りによる予期せぬエラーが発生しやすいため、try-catch による例外処理を適切に実装し、特に一時ディレクトリの作成や削除時には、意図しないファイルやディレクトリを操作しないよう細心の注意を払い、パスの厳密な管理を徹底してください。
PHPでRecursiveDirectoryIteratorを使い、現在の月に関連するファイルを検索する
1<?php 2 3/** 4 * 指定されたディレクトリ内で現在の月に関連するファイルを再帰的に検索します。 5 * RecursiveDirectoryIterator の `current()` メソッドが返す SplFileInfo オブジェクトを利用して、 6 * ファイル名に現在の月の情報が含まれているかをチェックします。 7 * 8 * @param string $directoryPath 検索対象のディレクトリのパス 9 * @return array<string> 現在の月に関連すると判断されたファイルの絶対パスの配列 10 */ 11function findCurrentMonthFiles(string $directoryPath): array 12{ 13 // 現在の月を2桁の数字(例: "01", "11")と、英語のフルネーム(例: "January", "November")で取得します。 14 $currentMonthNumber = date('m'); 15 $currentMonthNameFull = date('F'); 16 17 $foundFiles = []; // 見つかったファイルを格納する配列 18 19 // 検索対象のディレクトリが存在しない場合は、エラーメッセージを表示して空の配列を返します。 20 if (!is_dir($directoryPath)) { 21 echo "エラー: 指定されたディレクトリ '{$directoryPath}' が見つかりません。\n"; 22 return $foundFiles; 23 } 24 25 try { 26 // RecursiveDirectoryIterator を使用して、指定されたディレクトリを再帰的に走査します。 27 // RecursiveDirectoryIterator::SKIP_DOTS フラグは、'.'(現在のディレクトリ)と '..'(親ディレクトリ)をスキップします。 28 $directoryIterator = new RecursiveDirectoryIterator( 29 $directoryPath, 30 RecursiveDirectoryIterator::SKIP_DOTS 31 ); 32 33 // RecursiveIteratorIterator は、RecursiveDirectoryIterator が生成する 34 // 全てのファイルとサブディレクトリを単一のリストとしてイテレートできるようにします。 35 // RecursiveIteratorIterator::SELF_FIRST は、サブディレクトリ内のファイルより先に 36 // サブディレクトリ自体もイテレート対象に含めることを意味します。 37 $iterator = new RecursiveIteratorIterator( 38 $directoryIterator, 39 RecursiveIteratorIterator::SELF_FIRST 40 ); 41 42 // イテレータをループして、ディレクトリ内のすべてのファイルとディレクトリを処理します。 43 foreach ($iterator as $fileInfo) { 44 // ここで `$fileInfo` 変数には、イテレータの `current()` メソッドが返す 45 // 現在の要素(ファイルまたはディレクトリ)の SplFileInfo オブジェクトが自動的に代入されます。 46 // SplFileInfo オブジェクトは、ファイル名、パス、更新日時など、ファイルに関する詳細な情報を提供します。 47 48 // 現在の要素がファイルである場合にのみ処理を続けます。 49 if ($fileInfo->isFile()) { 50 $filename = $fileInfo->getFilename(); // ファイル名を取得します。 51 52 // ファイル名に現在の月を示す数字、または英語の月名が含まれているかをチェックします。 53 // stripos() 関数は大文字・小文字を区別せずに検索を行います。 54 if (stripos($filename, $currentMonthNumber) !== false || 55 stripos($filename, $currentMonthNameFull) !== false) { 56 $foundFiles[] = $fileInfo->getPathname(); // ファイルの絶対パスを結果配列に追加します。 57 } 58 } 59 } 60 } catch (UnexpectedValueException $e) { 61 // ディレクトリの読み込み中に何らかの問題が発生した場合の例外を捕捉します。 62 echo "エラー: ディレクトリの読み込み中に問題が発生しました: " . $e->getMessage() . "\n"; 63 } 64 65 return $foundFiles; 66} 67 68// --- サンプルコードの実行とテスト --- 69 70// テスト用のディレクトリを作成します。現在のスクリプトと同じディレクトリ内に作成されます。 71$testDir = __DIR__ . '/php_current_month_sample_data'; 72if (!is_dir($testDir)) { 73 mkdir($testDir, 0777, true); 74 echo "テストディレクトリ '{$testDir}' を作成しました。\n"; 75} 76 77// 現在の月情報を取得します。 78$currentMonthNum = date('m'); // 例: "11" 79$currentMonthName = date('F'); // 例: "November" 80 81// テストファイルを作成します。ファイル名に現在の月情報を含むものと含まないものを混ぜます。 82file_put_contents("{$testDir}/report_{$currentMonthNum}.txt", "今月のレポート内容。\n"); 83file_put_contents("{$testDir}/log_{$currentMonthName}.log", "今月のログエントリ。\n"); 84file_put_contents("{$testDir}/archive_2023_10.zip", "先月のアーカイブ。\n"); // 現在の月とは関係ないファイル 85 86// サブディレクトリを作成し、そこにもファイルを作成します。 87$subDir = "{$testDir}/monthly_data"; 88if (!is_dir($subDir)) { 89 mkdir($subDir, 0777, true); 90} 91file_put_contents("{$subDir}/summary_{$currentMonthNum}.csv", "今月の要約データ。\n"); 92file_put_contents("{$subDir}/expenses_january.xlsx", "1月の経費シート。\n"); // 現在の月とは関係ないファイル 93 94echo "\n--- 現在の月に関連するファイルを検索中 ---\n"; 95echo "対象ディレクトリ: {$testDir}\n"; 96echo "検索キーワード (月): 数字 '{$currentMonthNum}' または 英語名 '{$currentMonthName}'\n\n"; 97 98// 作成した関数を呼び出し、現在の月に関連するファイルを検索します。 99$monthlyFiles = findCurrentMonthFiles($testDir); 100 101if (!empty($monthlyFiles)) { 102 echo "現在の月に関連するファイルが見つかりました:\n"; 103 foreach ($monthlyFiles as $file) { 104 echo "- " . $file . "\n"; 105 } 106} else { 107 echo "現在の月に関連するファイルは見つかりませんでした。\n"; 108} 109 110// --- テストデータのクリーンアップ --- 111echo "\n--- テストデータをクリーンアップ中 ---\n"; 112 113// サブディレクトリ内のファイルを削除します。 114$subDirFiles = glob("{$subDir}/*"); 115if ($subDirFiles !== false) { 116 array_map('unlink', $subDirFiles); 117} 118// サブディレクトリを削除します。 119if (is_dir($subDir)) { 120 rmdir($subDir); 121} 122 123// メインディレクトリ内のファイルを削除します。 124$mainDirFiles = glob("{$testDir}/*"); 125if ($mainDirFiles !== false) { 126 array_map('unlink', $mainDirFiles); 127} 128// メインディレクトリを削除します。 129if (is_dir($testDir)) { 130 rmdir($testDir); 131} 132echo "テストデータとディレクトリを削除しました。\n";
このPHPサンプルコードは、指定されたディレクトリ内で現在の月に関連するファイルを再帰的に検索する方法を示しています。RecursiveDirectoryIteratorクラスはディレクトリの内容をイテレート(順に処理)するためのもので、これをRecursiveIteratorIteratorと組み合わせることで、サブディレクトリの中まで効率的にファイルを走査できます。
foreach ($iterator as $fileInfo) のループでは、各ファイルまたはディレクトリが処理されるたびに、イテレータの内部でRecursiveDirectoryIterator::current()メソッドが自動的に呼び出されます。このcurrent()メソッドは引数を受け取らず、現在処理している要素の詳細情報を含むSplFileInfoオブジェクトを戻り値として返します。
サンプルコードでは、このSplFileInfoオブジェクト(変数$fileInfo)を利用して、その要素がファイルであるか(isFile())を判断し、ファイルであればそのファイル名(getFilename())に現在の月の数字や英語名が含まれているかをチェックしています。SplFileInfoはファイル名、パス、更新日時など、ファイルに関する豊富な情報を提供するオブジェクトであり、これによって特定の条件に合致するファイルを特定し、その絶対パス(getPathname())を結果として収集しています。このように、current()メソッドが返すSplFileInfoオブジェクトは、ファイルシステムを扱う際に中心的な役割を果たします。
このコードでは、foreachループでイテレータを処理する際に、RecursiveDirectoryIteratorのcurrent()メソッドが自動的に呼び出され、SplFileInfoオブジェクトがループ変数に代入されます。このSplFileInfoオブジェクトはファイルの種類やパス、名前など豊富な情報を提供するため、ファイルシステムを安全かつ効率的に操作する上で非常に重要です。
再帰的なディレクトリ走査では、指定されたディレクトリが存在しない場合や、アクセス権限がない場合にUnexpectedValueExceptionなどの例外が発生する可能性がありますので、try-catchブロックによるエラーハンドリングは必ず実装してください。
また、date()関数で現在の月を取得する際は、PHPのタイムゾーン設定(date_default_timezone_set())によって結果が変わる可能性があるため、意図したタイムゾーンで実行されているか確認することが重要です。ファイル名の文字列検索は単純なマッチングであり、より厳密な条件でファイルを特定したい場合は正規表現の利用も検討してください。