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

【PHP8.x】GlobIterator::SKIP_DOTS定数の使い方

SKIP_DOTS定数の使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

GlobIterator::SKIP_DOTS定数は、ファイルシステム内の項目を効率的に走査する際に、「.」(カレントディレクトリ)と「..」(親ディレクトリ)という特殊なディレクトリを自動的にスキップするための定数です。GlobIteratorクラスは、指定されたパターン(例: *.txt)に一致するファイルやディレクトリを繰り返し処理(イテレーション)するために使用されます。通常、このクラスはディレクトリ内のすべてのエントリを対象としますが、アプリケーションによっては「.」と「..」といった特殊なエントリは処理の対象外としたい場合があります。

この定数をGlobIteratorのコンストラクタの第2引数にフラグとして渡すことで、これらの特殊なディレクトリが結果に含まれなくなり、余計なエントリをフィルタリングする手間が省けます。例えば、特定のディレクトリ内の実際のファイルやサブディレクトリのみをリストアップしたい場合、GlobIterator::SKIP_DOTSを使用することで、コード内でこれらのドットエントリを個別に除外するロジックを記述する必要がなくなります。これにより、開発者はよりクリーンで目的に合致した結果セットを簡単に得ることができ、イテレーション処理のロジックを簡素化できます。これは、ファイルやディレクトリの一覧表示、特定のファイル操作、または再帰的なディレクトリ走査など、さまざまなシナリオで特に有用です。この定数を利用することで、コードの可読性が向上し、エラーの発生を抑制しつつ、効率的なファイルシステム操作を実現できます。

構文(syntax)

1<?php
2$iterator = new GlobIterator(__DIR__ . '/*', GlobIterator::SKIP_DOTS);
3foreach ($iterator as $file) {
4    echo $file->getFilename() . PHP_EOL;
5}
6?>

引数(parameters)

引数なし

引数はありません

戻り値(return)

戻り値なし

戻り値はありません

サンプルコード

PHP GlobIterator::SKIP_DOTS でドットをスキップする

1<?php
2
3/**
4 * GlobIterator::SKIP_DOTS 定数の使用例を示す関数です。
5 * この定数を使用することで、ディレクトリ走査時に '.' (カレントディレクトリ) と '..' (親ディレクトリ) をスキップできます。
6 */
7function demonstrateGlobIteratorSkipDots(): void
8{
9    // 1. 一時的なテストディレクトリを作成します。
10    // PHPのパス区切り文字はOSによって異なるため、DIRECTORY_SEPARATOR を使用します。
11    $testDir = __DIR__ . DIRECTORY_SEPARATOR . 'test_dir_' . uniqid();
12    if (!mkdir($testDir) && !is_dir($testDir)) {
13        throw new \RuntimeException(sprintf('Directory "%s" was not created', $testDir));
14    }
15
16    // 2. テスト用のファイルとサブディレクトリを作成します。
17    file_put_contents($testDir . DIRECTORY_SEPARATOR . 'file1.txt', 'Hello');
18    file_put_contents($testDir . DIRECTORY_SEPARATOR . 'file2.txt', 'World');
19    mkdir($testDir . DIRECTORY_SEPARATOR . 'subdir');
20    // ドットファイル(隠しファイル)も作成し、イテレータがどのように扱うか確認します。
21    file_put_contents($testDir . DIRECTORY_SEPARATOR . '.hidden_file', 'Hidden content');
22
23    echo "--- GlobIterator::SKIP_DOTS を使用しない場合 ---" . PHP_EOL;
24    echo "('.'と'..'が表示される可能性があります)" . PHP_EOL;
25    try {
26        // GlobIterator の第1引数にディレクトリパスを直接渡します。
27        // 第2引数にフラグを指定しない(または0を指定する)場合、
28        // FilesystemIterator のデフォルトの挙動に基づき、'.' と '..' が結果に含まれることがあります。
29        $iteratorWithoutSkipDots = new GlobIterator($testDir);
30        foreach ($iteratorWithoutSkipDots as $path) {
31            echo "- " . $path->getFilename() . PHP_EOL;
32        }
33    } catch (Exception $e) {
34        echo "エラー: " . $e->getMessage() . PHP_EOL;
35    }
36    echo PHP_EOL;
37
38    echo "--- GlobIterator::SKIP_DOTS を使用する場合 ---" . PHP_EOL;
39    echo "('.'と'..'が結果から除外されます)" . PHP_EOL;
40    try {
41        // GlobIterator の第2引数に GlobIterator::SKIP_DOTS 定数を指定します。
42        // これにより、カレントディレクトリ(.)と親ディレクトリ(..)が結果から除外されます。
43        $iteratorWithSkipDots = new GlobIterator($testDir, GlobIterator::SKIP_DOTS);
44        foreach ($iteratorWithSkipDots as $path) {
45            echo "- " . $path->getFilename() . PHP_EOL;
46        }
47    } catch (Exception $e) {
48        echo "エラー: " . $e->getMessage() . PHP_EOL;
49    }
50    echo PHP_EOL;
51
52    // 3. クリーンアップ: 作成した一時ファイルとディレクトリを削除します。
53    // glob関数で、通常ファイルとドットファイル(隠しファイル)の両方を検索します。
54    // GLOB_BRACE は {} パターンを使用可能にします。
55    $items = glob($testDir . DIRECTORY_SEPARATOR . '{*,.*}', GLOB_BRACE);
56    foreach ($items as $item) {
57        if (is_file($item)) {
58            unlink($item);
59        } elseif (is_dir($item)) {
60            // 作成したサブディレクトリは空なので rmdir で削除できます。
61            rmdir($item);
62        }
63    }
64    // 最後にテストディレクトリ自体を削除します。
65    rmdir($testDir);
66}
67
68// 定義した関数を実行します。
69demonstrateGlobIteratorSkipDots();

PHPのGlobIterator::SKIP_DOTSは、GlobIteratorクラスがディレクトリ内の項目を走査する際に使用する特別な定数です。この定数自体には引数や戻り値はなく、ディレクトリの走査動作を制御するためのフラグとして機能します。

その主な役割は、ファイルやサブディレクトリの一覧を取得する際に、カレントディレクトリを示す「.」と親ディレクトリを示す「..」という特殊なエントリを結果から自動的に除外することです。

サンプルコードでは、まず一時的なテストディレクトリを作成し、その中にいくつかのファイルとサブディレクトリを用意しています。GlobIteratorのインスタンスを生成する際に、このGlobIterator::SKIP_DOTS定数を指定しない場合、走査結果に「.」や「..」が含まれる可能性があります。しかし、GlobIteratorのコンストラクタの第2引数にGlobIterator::SKIP_DOTSを指定すると、これらの特殊なエントリはスキップされ、実際に作成したファイルやディレクトリの名前のみが取得されます。

この定数を使用することで、目的のファイルやディレクトリに焦点を当てて処理を行うことができ、ディレクトリ構造の特殊なエントリを個別にフィルタリングする手間が省け、コードがより簡潔で意図が明確になります。プログラムの最後には、作成された一時ファイルとディレクトリは適切にクリーンアップされます。

GlobIterator::SKIP_DOTSは、ディレクトリ走査時に.(カレントディレクトリ)と..(親ディレクトリ)を結果から自動的に除外する定数です。これを指定しないと、これらの特殊なエントリがリストに含まれる可能性があります。意図しない処理を避けるため、除外したい場合はGlobIteratorコンストラクタの第2引数に必ず指定してください。ファイルパスの構築には、OSに依存しないDIRECTORY_SEPARATOR定数の使用が推奨されます。ファイルシステム操作ではエラーが発生しやすいため、try-catchによる適切な例外処理を心がけましょう。テストなどで一時的に作成したファイルやディレクトリは、処理後に確実にクリーンアップすることが重要です。特に、隠しファイルも考慮して削除対象に含めるよう注意してください。

GlobIterator::SKIP_DOTS でディレクトリ走査する

1<?php
2
3// 一時的なテストディレクトリのパスを定義します。
4$testDir = __DIR__ . '/temp_glob_dir';
5
6// テストディレクトリが存在しない場合は作成します。
7// 0777 はディレクトリのパーミッション(読み書き実行の全許可)、true は再帰的な作成を許可します。
8if (!is_dir($testDir)) {
9    mkdir($testDir, 0777, true);
10}
11
12// テストディレクトリ内にサンプルファイルとサブディレクトリを作成します。
13file_put_contents($testDir . DIRECTORY_SEPARATOR . 'file1.txt', 'Hello PHP');
14file_put_contents($testDir . DIRECTORY_SEPARATOR . 'report.log', 'Log entry');
15mkdir($testDir . DIRECTORY_SEPARATOR . 'data_dir', 0777, true);
16file_put_contents($testDir . DIRECTORY_SEPARATOR . 'data_dir' . DIRECTORY_SEPARATOR . 'config.ini', 'Setting=Value');
17
18echo "--- オリジナルディレクトリの内容 (scandir() を使用) ---\n";
19echo "scandir() は通常 '.' (カレントディレクトリ) と '..' (親ディレクトリ) を含みます。\n";
20foreach (scandir($testDir) as $item) {
21    echo "- " . $testDir . DIRECTORY_SEPARATOR . $item . "\n";
22}
23echo "\n";
24
25echo "--- GlobIterator::SKIP_DOTS を使用したディレクトリ走査 ---\n";
26echo "GlobIterator::SKIP_DOTS フラグにより '.' と '..' が自動的にスキップされます。\n";
27
28try {
29    // GlobIterator をインスタンス化し、指定されたパターンに一致する項目を走査します。
30    // $testDir . '/*' は、$testDir 内のすべてのファイルとディレクトリを対象とします。
31    // GlobIterator::SKIP_DOTS: '.' と '..' エントリをスキップします。
32    // GLOB_MARK: ディレクトリ名の末尾にスラッシュ '/' を追加します。
33    $iterator = new GlobIterator(
34        $testDir . DIRECTORY_SEPARATOR . '*',
35        GlobIterator::SKIP_DOTS | GLOB_MARK
36    );
37
38    // イテレータをループして、見つかった各項目を出力します。
39    // GlobIterator は SplFileInfo オブジェクトを返すため、getPathname() メソッドでフルパスを取得します。
40    foreach ($iterator as $fileInfo) {
41        echo $fileInfo->getPathname() . "\n";
42    }
43
44} catch (Exception $e) {
45    echo "エラーが発生しました: " . $e->getMessage() . "\n";
46} finally {
47    // スクリプトの実行後、作成した一時ディレクトリとファイルをクリーンアップします。
48    // 再帰的にディレクトリを削除するためのヘルパー関数です。
49    $rrmdir = function ($dir) use (&$rrmdir) {
50        if (!is_dir($dir)) {
51            return;
52        }
53        $objects = scandir($dir);
54        foreach ($objects as $object) {
55            if ($object != "." && $object != "..") {
56                if (is_dir($dir . DIRECTORY_SEPARATOR . $object)) {
57                    $rrmdir($dir . DIRECTORY_SEPARATOR . $object);
58                } else {
59                    unlink($dir . DIRECTORY_SEPARATOR . $object);
60                }
61            }
62        }
63        rmdir($dir);
64    };
65    $rrmdir($testDir);
66}

PHPのGlobIterator::SKIP_DOTSは、ファイルシステムのディレクトリを走査する際に、特殊なエントリである「.」(カレントディレクトリ)と「..」(親ディレクトリ)を自動的にスキップするための定数です。この定数自体は引数を取らず、特定の値を返すものではありません。通常、ディレクトリの内容をリストアップする関数ではこれらの特殊なエントリも含まれますが、GlobIteratorクラスのコンストラクタにこの定数をフラグとして渡すことで、これらの不要なエントリを除外した結果を得られます。サンプルコードでは、まずscandir()関数で「.」と「..」がリストに含まれる様子を示した後、GlobIteratorSKIP_DOTSフラグを適用することで、これらがきれいにスキップされ、目的のファイルやディレクトリのみが列挙されることを確認できます。これにより、ファイルやディレクトリの一覧を扱う処理がより効率的かつ簡潔になります。

GlobIterator::SKIP_DOTSは、ディレクトリ内の項目を走査する際、カレントディレクトリを示す「.」と親ディレクトリを示す「..」のエントリを自動的に除外できる便利な定数です。これにより、scandir()関数のようにこれらの特殊エントリを手動でフィルタリングする手間がなくなり、コードを簡潔に保てます。利用する際は、GlobIteratorクラスのコンストラクタのフラグ引数に指定し、必要に応じて他のフラグと|演算子で結合してください。走査対象のパスパターン(例: '/path/*')を正確に指定することが重要で、誤ったパターンでは意図した結果が得られません。また、ファイルシステム操作はエラーが発生しやすいため、try-catchブロックで例外処理を行うことを推奨いたします。

関連コンテンツ