Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】RecursiveDirectoryIterator::isDir()メソッドの使い方

isDirメソッドの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

isDirメソッドは、PHPのRecursiveDirectoryIteratorクラスに属し、現在のイテレータが指すファイルシステム上の要素がディレクトリであるかどうかを判定するメソッドです。

RecursiveDirectoryIteratorは、コンピュータのディレクトリ構造を再帰的に(つまり、ディレクトリの中のディレクトリも順に)探索するための強力なツールです。isDirメソッドは、その探索過程において現在イテレータが位置している項目が、ファイルなのか、それともさらに下層のファイルやディレクトリを含む「ディレクトリ」なのかを判別するために非常に重要な役割を果たします。

このメソッドを呼び出すと、現在のイテレータが位置している項目がディレクトリである場合にのみ真(true)を返します。もし現在の項目が通常のファイル、シンボリックリンク、またはその他の種類の要素である場合には偽(false)を返します。

システムエンジニアを目指す初心者の皆様が、例えば特定のディレクトリ以下のサブディレクトリだけを対象に処理を行いたい場合や、ファイルとディレクトリで異なる処理ロジックを適用したい場合などに、このisDirメソッドが役立ちます。特定のパスがディレクトリであるかを確認することで、不要なファイル操作を避けたり、意図しない挙動を防いだりする安全なプログラム構築に貢献します。このメソッドは引数を必要とせず、簡潔にディレクトリ判別を行います。

構文(syntax)

1<?php
2$iterator = new RecursiveDirectoryIterator(__DIR__);
3$recursiveIterator = new RecursiveIteratorIterator($iterator);
4
5foreach ($recursiveIterator as $fileInfo) {
6    if ($fileInfo->isDir()) {
7        echo "Directory: " . $fileInfo->getPathname() . "\n";
8    } else {
9        echo "File: " . $fileInfo->getPathname() . "\n";
10    }
11}

引数(parameters)

引数なし

引数はありません

戻り値(return)

bool

このメソッドは、現在のディレクトリ要素がディレクトリである場合に true を返します。ディレクトリでない場合は false を返します。

サンプルコード

PHP RecursiveDirectoryIteratorでisDir()を使う

1<?php
2
3/**
4 * テスト用のディレクトリとファイル構造を作成します。
5 *
6 * @param string $baseDir 作成するベースディレクトリ名
7 */
8function create_test_directory_structure(string $baseDir): void
9{
10    // 既存のディレクトリが存在する場合は先にクリーンアップします。
11    if (file_exists($baseDir)) {
12        cleanup_test_directory_structure($baseDir);
13    }
14
15    // ディレクトリを作成
16    mkdir($baseDir);
17    file_put_contents("$baseDir/file1.txt", "これはファイル1です。");
18
19    mkdir("$baseDir/subdir1");
20    file_put_contents("$baseDir/subdir1/file2.txt", "これはファイル2です。");
21
22    mkdir("$baseDir/subdir1/subsubdir1");
23    file_put_contents("$baseDir/subdir1/subsubdir1/file3.txt", "これはファイル3です。");
24
25    mkdir("$baseDir/subdir2");
26    mkdir("$baseDir/subdir2/empty_subdir"); // 空のサブディレクトリ
27
28    echo "テストディレクトリ構造 '$baseDir' を作成しました。\n\n";
29}
30
31/**
32 * テスト用のディレクトリとファイルを再帰的に削除します。
33 *
34 * @param string $dir 削除するディレクトリのパス
35 */
36function cleanup_test_directory_structure(string $dir): void
37{
38    if (!file_exists($dir)) {
39        return;
40    }
41    // ディレクトリの内容を走査し、ファイルまたはサブディレクトリを削除します。
42    $files = array_diff(scandir($dir), ['.', '..']);
43    foreach ($files as $file) {
44        $path = "$dir/$file";
45        // ディレクトリであれば再帰的に cleanup 関数を呼び出し、そうでなければファイルを削除します。
46        (is_dir($path)) ? cleanup_test_directory_structure($path) : unlink($path);
47    }
48    // ディレクトリが空になったら削除します。
49    rmdir($dir);
50    echo "テストディレクトリ構造 '$dir' を削除しました。\n\n";
51}
52
53/**
54 * RecursiveDirectoryIterator と isDir() メソッドの使用例を示します。
55 * 指定されたディレクトリとそのサブディレクトリを再帰的に走査し、
56 * 各要素がディレクトリであるかどうかを判定します。
57 */
58function demonstrateRecursiveDirectoryIteratorIsDir(): void
59{
60    $testDir = 'test_dir_for_is_dir_example';
61    create_test_directory_structure($testDir);
62
63    try {
64        echo "ディレクトリ '$testDir' の内容を走査し、各要素がディレクトリかファイルかを判定します。\n\n";
65
66        // RecursiveDirectoryIterator を使用して指定されたディレクトリのイテレータを作成します。
67        // FilesystemIterator::SKIP_DOTS を指定することで、'.' と '..' をスキップします。
68        $directoryIterator = new RecursiveDirectoryIterator($testDir, FilesystemIterator::SKIP_DOTS);
69
70        // RecursiveIteratorIterator を使用して、サブディレクトリも再帰的に走査します。
71        // RecursiveIteratorIterator::SELF_FIRST を指定することで、
72        // ディレクトリ自体も走査対象となり、その中身が走査される前に処理されます。
73        $iterator = new RecursiveIteratorIterator($directoryIterator, RecursiveIteratorIterator::SELF_FIRST);
74
75        // イテレータをループで走査します。
76        foreach ($iterator as $name => $fileInfo) {
77            // $fileInfo は SplFileInfo のインスタンスであり、
78            // RecursiveDirectoryIterator::isDir() メソッドは SplFileInfo::isDir() を利用して
79            // 現在の要素がディレクトリであるかどうかを真偽値 (bool) で返します。
80            $type = $fileInfo->isDir() ? 'ディレクトリ' : 'ファイル';
81
82            // 現在の要素のパスとそのタイプを表示します。
83            echo "パス: " . $fileInfo->getPathname() . " -> タイプ: " . $type . "\n";
84        }
85    } catch (Exception $e) {
86        // エラーが発生した場合、メッセージを表示します。
87        echo "エラーが発生しました: " . $e->getMessage() . "\n";
88    } finally {
89        // 処理が完了したら、作成したテストディレクトリをクリーンアップします。
90        cleanup_test_directory_structure($testDir);
91    }
92}
93
94// スクリプトを実行します。
95demonstrateRecursiveDirectoryIteratorIsDir();
96
97?>

RecursiveDirectoryIterator::isDir()は、PHP 8 のRecursiveDirectoryIteratorクラスで利用できるメソッドです。このメソッドは、現在処理中の要素がディレクトリであるかどうかを判定するために使用されます。

isDir()メソッドは引数を一切取らず、戻り値として真偽値 (bool) を返します。現在の要素がディレクトリであればtrueを、そうでなければ (ファイルなどであれば)falseを返します。この機能は、ファイルシステムを再帰的に走査する際に、各要素のタイプを判別し、異なる処理を行う場合に非常に有用です。

提供されたサンプルコードでは、まず一時的なテストディレクトリとファイル構造が作成されます。次に、RecursiveDirectoryIteratorを用いて指定されたディレクトリのイテレータを生成し、さらにRecursiveIteratorIteratorを使って、そのサブディレクトリまで含めて再帰的にすべての要素を走査します。ループ内で、$fileInfoオブジェクト(SplFileInfoのインスタンス)のisDir()メソッドが呼び出され、各要素がディレクトリであるかどうかが判定されます。その結果に基づいて、「ディレクトリ」または「ファイル」の区別が出力され、それぞれのパスが表示されます。このように、isDir()を利用することで、ディレクトリ構造全体を効率的に探索し、要素の種別に応じた処理を簡単に実装できます。処理の最後には、作成されたテストディレクトリは適切に削除されます。

RecursiveDirectoryIteratorを用いてディレクトリを走査する際、isDir()メソッドはSplFileInfoオブジェクトに対して使用します。これは、走査中に取得する各要素がディレクトリであるかを判定するために使われるものです。FilesystemIterator::SKIP_DOTSを指定することで、...といった特殊なディレクトリの誤判定を防ぎ、安全に処理できます。また、RecursiveIteratorIteratorと組み合わせることで、サブディレクトリまで再帰的に効率よく走査が可能です。ファイルシステムへのアクセスは、権限の問題やパスの誤りなどで失敗することがあります。そのため、サンプルコードのようにtry-catch-finallyブロックを用いてエラー処理を適切に行うことが、堅牢なプログラムを作成する上で非常に重要です。

RecursiveDirectoryIterator::isDir()でディレクトリ判定する

1<?php
2
3// このサンプルコードは、RecursiveDirectoryIterator を使用してディレクトリを走査し、
4// 各項目がディレクトリであるかどうかを isDir() メソッドで判定する方法を示します。
5// システムエンジニアを目指す初心者の方にも理解しやすいよう、コメントを付けています。
6//
7// 注: キーワード "php isdirty" と関連付けていますが、RecursiveDirectoryIterator クラスには
8//     "isDirty" というメソッドは存在せず、"isDir" (ディレクトリであるか判定) メソッドがあります。
9//     ここでは、ご提供のリファレンス情報に基づき "isDir" メソッドのサンプルコードを生成します。
10
11// ----------------------------------------------------
12// 1. サンプル実行用の仮ディレクトリとファイルを準備する
13// ----------------------------------------------------
14$baseDir = __DIR__ . DIRECTORY_SEPARATOR . 'temp_test_dir_for_is_dir';
15
16// もしディレクトリが存在しなければ作成します
17if (!is_dir($baseDir)) {
18    mkdir($baseDir, 0777, true); // 0777はアクセス権、trueは再帰的にディレクトリを作成
19}
20
21// テスト用のファイルを作成します
22file_put_contents($baseDir . DIRECTORY_SEPARATOR . 'document.txt', 'これはテキストファイルです。');
23
24// テスト用のサブディレクトリを作成します
25mkdir($baseDir . DIRECTORY_SEPARATOR . 'photos');
26file_put_contents($baseDir . DIRECTORY_SEPARATOR . 'photos' . DIRECTORY_SEPARATOR . 'image.jpg', '画像データ');
27
28// 別のサブディレクトリを作成します
29mkdir($baseDir . DIRECTORY_SEPARATOR . 'reports');
30
31echo "--- 準備されたディレクトリ構成 ---\n";
32echo "{$baseDir}/\n";
33echo "  document.txt\n";
34echo "  photos/\n";
35echo "    image.jpg\n";
36echo "  reports/\n";
37echo "----------------------------------\n\n";
38
39// ----------------------------------------------------
40// 2. RecursiveDirectoryIterator と isDir() メソッドを利用して走査する
41// ----------------------------------------------------
42try {
43    // RecursiveDirectoryIterator のインスタンスを作成します。
44    // これにより、指定したディレクトリの内容(ファイルやサブディレクトリ)をリストアップできるようになります。
45    $directoryIterator = new RecursiveDirectoryIterator($baseDir);
46
47    // RecursiveIteratorIterator を使用して、指定したディレクトリとそのサブディレクトリ全てを
48    // 再帰的に(つまり、階層を深く掘り下げて)走査します。
49    // RecursiveIteratorIterator::CHILD_FIRST は、子要素から親要素へ処理するモードです。
50    $recursiveIterator = new RecursiveIteratorIterator($directoryIterator, RecursiveIteratorIterator::CHILD_FIRST);
51
52    echo "--- RecursiveDirectoryIterator::isDir() の実行結果 ---\n";
53    foreach ($recursiveIterator as $fileInfo) {
54        // $fileInfo は現在のイテレータが指しているファイルまたはディレクトリの情報を持つオブジェクトです。
55        // isDir() メソッドは、現在の項目がディレクトリであれば true、そうでなければ false を返します。
56        if ($fileInfo->isDir()) {
57            echo "[D] ディレクトリ: " . $fileInfo->getPathname() . "\n";
58        } else {
59            echo "[F] ファイル    : " . $fileInfo->getPathname() . "\n";
60        }
61    }
62    echo "------------------------------------------------------\n";
63
64} catch (UnexpectedValueException $e) {
65    // 指定されたパスが見つからない場合や、アクセス権がない場合に発生するエラーを捕捉します。
66    echo "エラーが発生しました: " . $e->getMessage() . "\n";
67} finally {
68    // ----------------------------------------------------
69    // 3. サンプル実行後に作成したディレクトリとファイルをクリーンアップする
70    // ----------------------------------------------------
71    // 再帰的にディレクトリを削除するためのヘルパー関数
72    function rrmdir_for_sample_cleanup($dir) {
73        if (!is_dir($dir)) {
74            return; // ディレクトリが存在しなければ何もしない
75        }
76        $objects = scandir($dir); // ディレクトリ内の全要素を取得
77        foreach ($objects as $object) {
78            if ($object != "." && $object != "..") { // "."と".."(カレント/親ディレクトリ)は無視
79                $path = $dir . DIRECTORY_SEPARATOR . $object;
80                if (is_dir($path) && !is_link($path)) {
81                    rrmdir_for_sample_cleanup($path); // サブディレクトリであれば再帰的に削除
82                } else {
83                    unlink($path); // ファイルであれば削除
84                }
85            }
86        }
87        rmdir($dir); // 最後に空になったディレクトリ自体を削除
88    }
89
90    rrmdir_for_sample_cleanup($baseDir); // 作成した仮ディレクトリを削除
91    echo "\n一時ディレクトリ '{$baseDir}' をクリーンアップしました。\n";
92}
93
94?>

PHPのRecursiveDirectoryIteratorクラスは、指定したディレクトリとそのサブディレクトリ内のファイルやフォルダを効率的に走査する際に利用されます。このクラスに属するisDir()メソッドは、現在イテレータが指している項目がディレクトリであるかどうかを判定するためのものです。

このサンプルコードでは、まず一時的なディレクトリとファイルを準備し、次にRecursiveDirectoryIteratorRecursiveIteratorIteratorを組み合わせて、作成したディレクトリツリーを再帰的に巡回しています。巡回中に各項目に対してisDir()メソッドが呼び出されます。このメソッドは引数を必要とせず、現在の項目がディレクトリであれば真偽値のtrueを、ファイルなどディレクトリ以外のものであればfalseを戻り値として返します。

プログラムは、このisDir()メソッドの戻り値に基づいて、表示する内容を「ディレクトリ」か「ファイル」かで正確に区別して出力しています。この機能は、特定のディレクトリ構造を解析したり、フォルダ内にあるファイルだけを処理したり、あるいは特定の条件を満たすサブディレクトリを見つけ出したりするなど、ファイルシステムを操作するさまざまなシナリオで基本的ながらも重要な役割を果たします。

isDir() メソッドは、ディレクトリを走査する際に、現在の要素がディレクトリであるかどうかを真偽値(trueまたはfalse)で判定するために使用します。このサンプルコードは、RecursiveDirectoryIteratorRecursiveIteratorIterator を組み合わせて利用することで、指定されたディレクトリとそのサブディレクトリ全体を効率的に再帰走査し、各項目を正確に識別する方法を示しています。

特に、サンプルコードでは実行後に作成した一時ディレクトリを安全にクリーンアップする処理が組み込まれています。実際のシステムでファイルやディレクトリを操作する際は、意図しないデータの変更や削除を防ぐため、対象パスやアクセス権限の確認を徹底し、例外処理を適切に実装することが非常に重要です。

関連コンテンツ