【PHP8.x】RecursiveDirectoryIterator::getFilename()メソッドの使い方
getFilenameメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
getFilenameメソッドは、PHPのRecursiveDirectoryIteratorクラスに属し、現在イテレータが指し示しているファイルやディレクトリの名前を取得するメソッドです。RecursiveDirectoryIteratorは、指定されたディレクトリ内のファイルだけでなく、そのサブディレクトリに存在するファイルやディレクトリもすべて順番に処理するために利用されるクラスです。このメソッドを使うと、例えば「/path/to/project/src/main.php」というような完全なパスを持つファイルに対して、「main.php」というファイル名だけを文字列として取得することができます。
ディレクトリを再帰的に走査する際、ファイルやディレクトリのフルパスではなく、その名前の部分だけを取り出して処理したい場合に非常に便利です。例えば、特定の名前のファイルを探したり、ファイル名に基づいて条件分岐を行ったり、あるいはログ出力にファイル名を活用したりする場面で使われます。戻り値は常に文字列型で、現在の要素のファイル名またはディレクトリ名が返されます。もし、ファイルやディレクトリの完全なパス(ディレクトリパスとファイル名を結合したもの)を取得したい場合には、getFilenameメソッドの代わりにgetPathname()メソッドを使用します。このメソッドは、ディレクトリ走査中に個々の要素の名前を簡潔かつ正確に取得するための基本的な機能を提供します。
構文(syntax)
1<?php 2 3// 対象となるディレクトリのパスを指定します。 4// この例では、現在のスクリプトが配置されているディレクトリを使用します。 5$directoryPath = __DIR__; 6 7// RecursiveDirectoryIterator のインスタンスを作成します。 8$iterator = new RecursiveDirectoryIterator($directoryPath); 9 10// ディレクトリ内の各要素(ファイルやサブディレクトリ)を反復処理します。 11foreach ($iterator as $item) { 12 // getFilename() メソッドを使って、現在の要素のファイル名またはディレクトリ名を取得し、表示します。 13 echo $item->getFilename() . "\n"; 14} 15 16?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
string
現在のディレクトリ要素のファイル名を表す文字列を返します。
サンプルコード
PHP RecursiveDirectoryIterator::getFilename() でファイル名を取得する
1<?php 2 3/** 4 * RecursiveDirectoryIterator::getFilename() メソッドの使用方法を示すサンプルコード。 5 * 6 * この関数は一時ディレクトリを作成し、その中にダミーファイルとサブディレクトリを配置します。 7 * その後、RecursiveDirectoryIterator と RecursiveIteratorIterator を使用してディレクトリを走査し、 8 * 各ファイルやディレクトリの名前を getFilename() メソッドで取得して表示します。 9 * 最後に、作成した一時ディレクトリをクリーンアップします。 10 */ 11function demonstrateRecursiveDirectoryIteratorGetFilename(): void 12{ 13 // 一時ディレクトリをシステムの一時パスに作成し、ユニークな名前を生成 14 $tempDir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . uniqid('php_getfilename_demo_'); 15 16 // ディレクトリ作成を試みる。失敗した場合はエラーをスロー。 17 if (!mkdir($tempDir) && !is_dir($tempDir)) { 18 throw new RuntimeException(sprintf('ディレクトリ "%s" の作成に失敗しました。', $tempDir)); 19 } 20 21 // スクリプト終了時に作成した一時ディレクトリを確実に削除するためのシャットダウン関数を登録。 22 // これにより、エラーが発生した場合でもディレクトリが残らないようにする。 23 register_shutdown_function(function () use ($tempDir) { 24 if (is_dir($tempDir)) { 25 // ディレクトリとその内容を再帰的に削除するヘルパー関数 (クロージャとして定義) 26 $rrmdir = function (string $dir) use (&$rrmdir): void { 27 if (!is_dir($dir)) { 28 return; 29 } 30 $files = array_diff(scandir($dir), ['.', '..']); 31 foreach ($files as $file) { 32 $path = $dir . DIRECTORY_SEPARATOR . $file; 33 (is_dir($path)) ? $rrmdir($path) : unlink($path); 34 } 35 rmdir($dir); 36 }; 37 $rrmdir($tempDir); 38 echo "\n--- 一時ディレクトリをクリーンアップしました: " . $tempDir . " ---\n"; 39 } 40 }); 41 42 echo "--- 一時ディレクトリを作成しました: " . $tempDir . " ---\n\n"; 43 44 // ダミーファイルとサブディレクトリを作成 45 file_put_contents($tempDir . DIRECTORY_SEPARATOR . 'file_a.txt', 'コンテンツA'); 46 file_put_contents($tempDir . DIRECTORY_SEPARATOR . 'another_file.log', 'ログ情報'); 47 mkdir($tempDir . DIRECTORY_SEPARATOR . 'sub_folder'); 48 file_put_contents($tempDir . DIRECTORY_SEPARATOR . 'sub_folder' . DIRECTORY_SEPARATOR . 'file_b.json', '{"key": "value"}'); 49 mkdir($tempDir . DIRECTORY_SEPARATOR . 'sub_folder' . DIRECTORY_SEPARATOR . 'empty_folder'); 50 51 echo "--- 作成されたディレクトリ構造 ---\n"; 52 echo $tempDir . "\n"; 53 echo "├── file_a.txt\n"; 54 echo "├── another_file.log\n"; 55 echo "└── sub_folder/\n"; 56 echo " ├── file_b.json\n"; 57 echo " └── empty_folder/\n\n"; 58 59 echo "--- RecursiveDirectoryIterator::getFilename() の結果 ---\n"; 60 61 try { 62 // RecursiveDirectoryIterator を使用して指定されたディレクトリを走査開始。 63 // RecursiveDirectoryIterator::SKIP_DOTS フラグにより、'.' と '..' (現在のディレクトリと親ディレクトリ) をスキップする。 64 $iterator = new RecursiveDirectoryIterator($tempDir, RecursiveDirectoryIterator::SKIP_DOTS); 65 66 // RecursiveIteratorIterator を使用して、サブディレクトリも再帰的に走査できるようにする。 67 $recursiveIterator = new RecursiveIteratorIterator($iterator); 68 69 // 走査された各ファイルやディレクトリに対してループ処理 70 foreach ($recursiveIterator as $item) { 71 // RecursiveDirectoryIterator::getFilename() メソッドで、 72 // 現在のファイルまたはディレクトリの名前のみを取得 (例: "file_a.txt", "sub_folder") 73 $filename = $item->getFilename(); 74 75 // 取得した名前とフルパスを表示 76 echo sprintf(" 名前: '%s' (フルパス: %s)\n", $filename, $item->getPathname()); 77 } 78 } catch (UnexpectedValueException $e) { 79 // ディレクトリが見つからない、またはアクセスできない場合のエラーハンドリング 80 echo "エラー: ディレクトリの読み込みに失敗しました - " . $e->getMessage() . "\n"; 81 } 82} 83 84// デモンストレーション関数を実行 85demonstrateRecursiveDirectoryIteratorGetFilename(); 86
PHP 8のRecursiveDirectoryIterator::getFilename()メソッドは、ファイルシステムを再帰的に走査する際に、現在処理しているファイルまたはディレクトリの名前を取得するために使用されます。このメソッドは引数を取らず、戻り値としてファイル名やディレクトリ名を文字列で返します。
サンプルコードでは、まず一時ディレクトリを作成し、その中に複数のダミーファイルとサブディレクトリを配置して、実際のファイルシステムのような構造をシミュレートします。スクリプトの終了時には、作成した一時ディレクトリが自動的に削除されるように設定されています。
次に、RecursiveDirectoryIteratorとRecursiveIteratorIteratorを組み合わせて使用し、作成した一時ディレクトリとそのサブディレクトリの内容を再帰的に走査します。これにより、すべてのファイルやディレクトリにアクセスできるようになります。
ループ処理の中で、$item->getFilename()を呼び出すことで、現在走査している項目(ファイルまたはディレクトリ)の「名前だけ」を取得しています。例えば、フルパスが/tmp/.../sub_folder/file_b.jsonであっても、getFilename()メソッドはfile_b.jsonという部分のみを返します。このメソッドは、パスからファイル名だけを抽出したい場合に非常に便利です。
getFilename()メソッドは、ファイルやディレクトリのフルパスではなく、その名前部分のみを返します。再帰的なディレクトリ走査にはRecursiveDirectoryIteratorとRecursiveIteratorIteratorを組み合わせ、RecursiveDirectoryIterator::SKIP_DOTSフラグで.や..といった特殊なディレクトリ名をスキップするのが安全です。ファイルシステムを操作するコードでは、一時的に作成したディレクトリやファイルをスクリプト終了時に確実に削除するクリーンアップ処理が非常に重要です。また、ファイルやディレクトリへのアクセスは、権限不足やパスの誤りによってエラーが発生しやすいため、try-catchブロックを用いた適切なエラーハンドリングを必ず行ってください。
PHP RecursiveDirectoryIterator でファイル名を取得する
1<?php 2 3/** 4 * RecursiveDirectoryIterator の getFilename() メソッドの使用例。 5 * 一時ディレクトリを作成し、その中のファイルやディレクトリ名を再帰的に取得・表示します。 6 */ 7 8// 1. テスト用の一時ディレクトリとファイルを作成 9// システムの一時ディレクトリパスを取得し、ユニークな名前でディレクトリを作成します。 10$tempDir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'php_example_dir_' . uniqid(); 11 12if (!mkdir($tempDir, 0777, true)) { 13 die("エラー: テストディレクトリの作成に失敗しました: " . $tempDir); 14} 15// テストファイルをいくつか作成 16file_put_contents($tempDir . DIRECTORY_SEPARATOR . 'document.txt', 'Sample text.'); 17file_put_contents($tempDir . DIRECTORY_SEPARATOR . 'image.jpg', 'Binary content.'); 18// サブディレクトリを作成し、その中にもファイルを作成 19mkdir($tempDir . DIRECTORY_SEPARATOR . 'logs'); 20file_put_contents($tempDir . DIRECTORY_SEPARATOR . 'logs' . DIRECTORY_SEPARATOR . 'app.log', 'Log data.'); 21 22echo "--- ディレクトリ構造を再帰的に走査し、ファイル名を表示します ---\n"; 23echo "対象ディレクトリ: " . $tempDir . "\n\n"; 24 25try { 26 // 2. RecursiveDirectoryIterator をインスタンス化 27 // 指定されたディレクトリのイテレータを作成します。 28 // RecursiveDirectoryIterator::SKIP_DOTS は "." と ".." をスキップします。 29 $directoryIterator = new RecursiveDirectoryIterator($tempDir, RecursiveDirectoryIterator::SKIP_DOTS); 30 31 // 3. RecursiveIteratorIterator を使用して再帰的に走査 32 // RecursiveDirectoryIterator をラップして、サブディレクトリも含めて走査できるようにします。 33 // RecursiveIteratorIterator::SELF_FIRST は、ディレクトリ自体をその内容より先に処理します。 34 $iterator = new RecursiveIteratorIterator($directoryIterator, RecursiveIteratorIterator::SELF_FIRST); 35 36 // 4. 各要素をループし、getFilename() でファイル名を取得・表示 37 foreach ($iterator as $fileInfo) { 38 // SplFileInfo::getFilename() メソッドは、パスのファイル名部分(ベース名)を返します。 39 // 例: '/path/to/my_file.txt' から 'my_file.txt' を、 40 // '/path/to/my_dir' から 'my_dir' を取得します。 41 echo $fileInfo->getFilename() . "\n"; 42 } 43 44} catch (UnexpectedValueException $e) { 45 echo "エラー: 指定されたパスが見つからないか、ディレクトリではありません。\n"; 46 echo $e->getMessage() . "\n"; 47} finally { 48 // 5. テスト用に作成したディレクトリとファイルをクリーンアップ 49 // RecursiveIteratorIterator::CHILD_FIRST を使用して、子要素(ファイルやサブディレクトリの内容)を 50 // 親ディレクトリより先に削除するようにします。 51 if (file_exists($tempDir)) { 52 $cleanupIterator = new RecursiveIteratorIterator( 53 new RecursiveDirectoryIterator($tempDir, RecursiveDirectoryIterator::SKIP_DOTS), 54 RecursiveIteratorIterator::CHILD_FIRST 55 ); 56 57 foreach ($cleanupIterator as $item) { 58 if ($item->isDir()) { 59 rmdir($item->getRealPath()); // ディレクトリを削除 60 } else { 61 unlink($item->getRealPath()); // ファイルを削除 62 } 63 } 64 rmdir($tempDir); // 最後にルートディレクトリを削除 65 echo "\n--- テストディレクトリとその内容をクリーンアップしました ---\n"; 66 } 67}
PHPのRecursiveDirectoryIteratorクラスが提供するgetFilename()メソッドは、ファイルやディレクトリのフルパスから、その名前の部分だけを文字列として取得するためのものです。このメソッドは引数を一切必要とせず、ファイル名やディレクトリ名を文字列(string)として返します。例えば、/path/to/document.txtというパスからはdocument.txtを、/path/to/imagesというパスからはimagesを取得します。
サンプルコードでは、まずテスト用に一時的なディレクトリといくつかのファイルやサブディレクトリを作成します。次に、RecursiveDirectoryIteratorとRecursiveIteratorIteratorを使用して、作成したディレクトリ構造を再帰的に(サブディレクトリの中まで)走査します。この走査中に見つかる各要素(ファイルやディレクトリ)の情報に対してgetFilename()メソッドを呼び出し、その名前を画面に表示しています。
このメソッドは、ディレクトリ内のすべてのファイルやサブディレクトリの名前を効率的にリストアップする際に非常に役立ちます。フルパスから必要な名前の部分だけを簡単に取り出せるため、ディレクトリ構造を扱うプログラムの構築において、コードを簡潔にし、可読性を向上させることができます。最後に、テスト用に作成した一時ディレクトリとその内容を確実に削除するクリーンアップ処理も行われています。
RecursiveDirectoryIterator::getFilename()メソッドは、ファイルやディレクトリのフルパスではなく、名前の部分(例: document.txtやlogs)のみを文字列で返します。サブディレクトリの中身も処理するには、RecursiveDirectoryIteratorとRecursiveIteratorIteratorを組み合わせて使用する必要がある点に注意してください。.や..といった特殊なディレクトリは、RecursiveDirectoryIterator::SKIP_DOTSフラグを使うと自動的にスキップされ、処理が簡潔になります。ファイルシステム操作は失敗することがあるため、try-catchでエラーを適切に処理し、一時的に作成したディレクトリやファイルは、finallyブロックなどで必ずクリーンアップするように心がけましょう。特にディレクトリ削除時は、内部のファイルやサブディレクトリを先に削除する順番が重要です。