【PHP8.x】opendir関数の使い方

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

作成日: 更新日:

基本的な使い方

opendir関数は、指定されたパスにあるディレクトリを開き、そのディレクトリの内容を読み書きするための準備を実行する関数です。この関数が正常に実行されると、開いたディレクトリを参照するための「ディレクトリハンドル」と呼ばれる特別なリソースを返します。このディレクトリハンドルは、その後のディレクトリ操作において、どのディレクトリに対して処理を行うかを識別するための「ID」のような役割を果たします。

例えば、opendir関数で開いたディレクトリから、readdir()関数を使ってファイルやディレクトリの名前を一つずつ読み込んだり、rewinddir()関数で読み込み位置を先頭に戻したり、closedir()関数で開いたディレクトリを閉じる際にこのハンドルを使用します。

指定されたパスにディレクトリが存在しない場合や、アクセス権限がないなどの理由でディレクトリを開くことができなかった場合には、opendir関数はfalse(偽)を返します。そのため、関数がfalseを返した場合はエラー処理を行う必要があります。ディレクトリ操作の完了後は、システムリソースの無駄な消費を防ぎ、予期せぬ問題を回避するために、必ずclosedir()関数を使って開いたディレクトリを閉じるようにしてください。

構文(syntax)

1<?php
2$directoryHandle = opendir('/path/to/your/directory');
3?>

引数(parameters)

string $directory, ?resource $context = null

  • string $directory: 開くディレクトリのパスを指定する文字列
  • ?resource $context = null: ストリームコンテキストを指定するリソース(省略可能、デフォルトはnull)

戻り値(return)

resource|false

ディレクトリを開くためのリソース、または失敗した場合は false を返します。

サンプルコード

PHPでディレクトリ内容をソートする

1<?php
2
3/**
4 * 指定されたディレクトリ内のエントリ(ファイルおよびディレクトリ)を読み込み、
5 * 名前順にソートして表示します。
6 * "." と ".." は除外されます。
7 *
8 * @param string $directoryPath 読み込むディレクトリのパス。
9 * @return void
10 */
11function listSortedDirectoryContents(string $directoryPath): void
12{
13    // ディレクトリを開く
14    $dirHandle = opendir($directoryPath);
15
16    // ディレクトリが開けなかった場合の処理
17    if ($dirHandle === false) {
18        echo "エラー: ディレクトリ '{$directoryPath}' を開けませんでした。\n";
19        return;
20    }
21
22    $entries = []; // ディレクトリ内のエントリを格納する配列
23
24    // ディレクトリ内のエントリを一つずつ読み込む
25    while (($entry = readdir($dirHandle)) !== false) {
26        // "." と ".." は特殊なエントリなので除外する
27        if ($entry !== '.' && $entry !== '..') {
28            $entries[] = $entry; // 配列に追加
29        }
30    }
31
32    // ディレクトリハンドルを閉じる
33    closedir($dirHandle);
34
35    // エントリをアルファベット順にソートする
36    sort($entries);
37
38    echo "ディレクトリ '{$directoryPath}' 内のソートされたエントリ:\n";
39    // ソートされたエントリを表示する
40    foreach ($entries as $entry) {
41        echo "- " . $entry . "\n";
42    }
43}
44
45// サンプル使用: 現在のスクリプトがあるディレクトリの内容を表示します。
46// 実行前に、このスクリプトと同じディレクトリ内にいくつかのファイルやサブディレクトリを作成して試してみてください。
47// 例:
48// - fileA.txt
49// - fileB.txt
50// - sub_dir/
51listSortedDirectoryContents(__DIR__);
52
53// 存在しないディレクトリを指定した場合の例
54// listSortedDirectoryContents('./non_existent_directory');
55
56?>

このPHPコードは、指定されたディレクトリ内のファイルやサブディレクトリといったエントリを読み込み、アルファベット順にソートして表示する手順を示しています。

核となるのはopendir関数です。この関数は、引数として開きたいディレクトリのパス(文字列)を受け取ります。処理が成功すると、そのディレクトリを操作するための「ディレクトリハンドル」と呼ばれるリソース型を返します。もし指定されたディレクトリが見つからない、またはアクセス権がないなどの理由で開けない場合はfalseを返しますので、コードではif ($dirHandle === false)のように、必ず戻り値がfalseでないかを確認し、適切にエラー処理を行うことが重要です。

ディレクトリが開かれると、readdir関数を使って内部のエントリを一つずつ繰り返し読み込みます。この時、特殊なエントリであるカレントディレクトリを示す「.」と親ディレクトリを示す「..」は、通常表示から除外されます。全てのエントリの読み込みが完了したら、開いたディレクトリハンドルはclosedir`関数を使って必ず閉じる必要があります。

読み込んだエントリは配列に格納され、PHPの標準関数であるsortによって名前順にソートされます。最終的に、ソートされたエントリが一覧として画面に出力されます。このように、opendirはディレクトリ操作の最初の一歩となる重要な関数であり、一連の処理とエラーハンドリングが適切に行われることで、堅牢なファイルシステム操作が可能になります。

PHPでディレクトリを操作する際は、opendirが失敗時にfalseを返すため、必ずエラーハンドリングを行いましょう。開いたディレクトリは、処理終了後にclosedirで確実に閉じることで、リソースの解放を忘れないことが重要です。また、readdirで読み込まれるカレントディレクトリ(.)と親ディレクトリ(..)は通常除外する処理が必要です。opendirreaddirの順序は保証されないため、名前順に表示したい場合は、サンプルコードのようにsort関数などで明示的にソートする必要があります。これらの点に注意し、安全にコードを利用してください。

PHPでディレクトリ内容を自然順ソートする

1<?php
2
3/**
4 * 指定されたディレクトリの内容を読み込み、ファイル名とディレクトリ名を自然順にソートして返します。
5 *
6 * @param string $directory 読み込むディレクトリのパス。
7 * @return array<string> ソートされたファイル名とディレクトリ名のリスト。エラーが発生した場合は空の配列。
8 */
9function getSortedDirectoryContents(string $directory): array
10{
11    $items = []; // ディレクトリの内容を格納する配列
12
13    // ディレクトリが存在し、実際にディレクトリであることを確認
14    if (!is_dir($directory)) {
15        echo "エラー: 指定されたパス '{$directory}' はディレクトリではありません、または存在しません。\n";
16        return [];
17    }
18
19    // ディレクトリをオープン
20    // opendir() はディレクトリハンドル (リソース) または false を返します。
21    $dirHandle = opendir($directory);
22
23    if ($dirHandle === false) {
24        echo "エラー: ディレクトリ '{$directory}' を開くことができませんでした。\n";
25        return [];
26    }
27
28    // ディレクトリからエントリを一つずつ読み込む
29    // readdir() は、次のファイル名またはディレクトリ名を返すか、末尾に達すると false を返します。
30    while (($item = readdir($dirHandle)) !== false) {
31        // '.' と '..' は現在のディレクトリと親ディレクトリを表すため、通常は除外します。
32        if ($item !== '.' && $item !== '..') {
33            $items[] = $item; // 配列に項目を追加
34        }
35    }
36
37    // 開いたディレクトリハンドルをクローズ
38    closedir($dirHandle);
39
40    // 読み込んだ項目を自然順でソート
41    // natsort() は 'file1.txt', 'file10.txt', 'file2.txt' のような項目を
42    // 'file1.txt', 'file2.txt', 'file10.txt' のようにソートします。
43    natsort($items);
44
45    // ソート後にキーが再インデックスされるように array_values() を使用
46    return array_values($items);
47}
48
49// スクリプトが実行されている現在のディレクトリを対象とする
50$targetDirectory = __DIR__;
51
52echo "ディレクトリ '{$targetDirectory}' の内容 (自然順ソート):\n";
53
54// ディレクトリの内容を取得し、表示
55$sortedItems = getSortedDirectoryContents($targetDirectory);
56
57if (!empty($sortedItems)) {
58    foreach ($sortedItems as $item) {
59        echo "- " . $item . "\n";
60    }
61} else {
62    echo "ソートされた項目はありません、またはエラーが発生しました。\n";
63}
64
65?>

このPHPサンプルコードは、指定されたディレクトリの内容を読み込み、ファイル名とディレクトリ名を自然順にソートして表示するものです。中心となるopendir関数は、指定されたディレクトリをオープンし、そのディレクトリを操作するための「ディレクトリハンドル」と呼ばれるリソースを返します。引数$directoryには、開きたいディレクトリのパスを指定します。もしディレクトリのオープンに成功すればリソース型のディレクトリハンドルが返され、失敗した場合はfalseが返されるため、その後の処理でfalseかどうかを確認し、エラーに対処することが重要です。

サンプルコードでは、まずis_dir関数でパスが有効なディレクトリかを確認し、opendirでディレクトリを開きます。成功した場合、readdir関数を使ってディレクトリハンドルからファイルやディレクトリの名前を一つずつ読み込みます。読み込みが完了したら、closedir関数で開いたディレクトリハンドルを必ず閉じる必要があります。読み込んだ項目は、人間の感覚に近い順序でソートするnatsort関数によって自然順に並べ替えられ、最終的にソートされたリストが返されます。これにより、初心者の方でもディレクトリ操作の基本とエラー処理、そしてソートの概念を理解することができます。

opendir関数を使用する際は、まずディレクトリが開けたか、戻り値がfalseでないかを確認し、エラー処理を適切に行ってください。ディレクトリを開けた場合は、処理完了後に必ずclosedir関数でリソースを解放することが重要です。これを怠ると、システムリソースを消費し続け、プログラムの不安定化につながります。readdir関数は、カレントディレクトリを示す.と親ディレクトリを示す..も返しますので、これらを結果に含めない場合は、サンプルコードのように明示的に除外処理を行ってください。また、$directoryパスがユーザー入力など外部からのものである場合、ディレクトリトラバーサルなどのセキュリティリスクを避けるため、パスの検証とサニタイズを必ず行ってください。全ファイルを一度に配列として取得したい場合はscandir関数がより簡潔な選択肢ですが、大量のファイルが存在する際はopendirreaddirの組み合わせがメモリ効率面で有利な場合があります。

関連コンテンツ

【PHP8.x】opendir関数の使い方 | いっしー@Webエンジニア