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

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

作成日: 更新日:

基本的な使い方

rmdir関数は、指定されたパスにある空のディレクトリ(フォルダ)を削除する関数です。この関数は、ファイルシステムを操作する際に、不要になったディレクトリをプログラムから削除するために利用されます。

rmdir関数を使用する際は、削除したいディレクトリのパスを文字列として引数に指定します。例えば、'path/to/empty_directory'のように記述します。指定されたディレクトリが正常に削除された場合、この関数はブール値のtrueを返します。しかし、何らかの理由で削除に失敗した場合はfalseを返します。失敗する主な理由としては、指定されたパスが存在しない、ディレクトリが空ではない、またはスクリプトにそのディレクトリを削除する適切な権限がない、などが挙げられます。

特に重要な点として、rmdir関数は空のディレクトリしか削除できません。もし削除しようとしているディレクトリ内にファイルやサブディレクトリが存在する場合、rmdir関数は失敗し、falseを返します。したがって、ディレクトリとその中のすべてのコンテンツを完全に削除したい場合は、まずそのディレクトリ内のすべてのファイルやサブディレクトリを再帰的に削除してから、最後にrmdir関数を使用して空になったディレクトリ自体を削除する必要があります。また、スクリプトがディレクトリを削除するためには、実行環境におけるファイルシステムへの書き込み権限が必要となるため、権限設定にも注意が必要です。関数がfalseを返した際には、PHPのエラーログを確認することで、失敗の原因を特定できます。

構文(syntax)

1<?php
2$directory_to_remove = 'my_empty_directory';
3
4// rmdir関数の動作を示すため、まず一時的な空のディレクトリを作成します。
5if (!is_dir($directory_to_remove)) {
6    mkdir($directory_to_remove);
7}
8
9// rmdir関数を使用して、指定されたパスの空のディレクトリを削除します。
10// 成功した場合はtrue、失敗した場合はfalseを返します。
11$is_removed = rmdir($directory_to_remove);
12
13if ($is_removed) {
14    echo "ディレクトリ '{$directory_to_remove}' は正常に削除されました。\n";
15} else {
16    echo "ディレクトリ '{$directory_to_remove}' の削除に失敗しました。\n";
17}

引数(parameters)

string $directory, ?resource $context = null

  • string $directory: 削除したいディレクトリのパスを指定します。
  • ?resource $context = null: ストリームコンテキストを指定します。指定しない場合は null が使用されます。

戻り値(return)

bool

指定されたディレクトリを削除する関数です。削除に成功した場合は true を、失敗した場合は false を返します。

サンプルコード

PHPでディレクトリをファイルごと削除する

1<?php
2
3/**
4 * 指定されたディレクトリとその中身(ファイル、サブディレクトリ)を再帰的に削除します。
5 *
6 * PHPのrmdir()は空のディレクトリしか削除できません。
7 * この関数は、まずディレクトリ内のすべてのファイルとサブディレクトリを削除してから、
8 * 最後に指定されたディレクトリ自体を削除します。
9 *
10 * @param string $dirPath 削除するディレクトリのパス
11 * @return bool すべての削除処理が成功した場合は true、それ以外は false
12 */
13function deleteDirectoryRecursively(string $dirPath): bool
14{
15    // ディレクトリが存在しない、またはディレクトリではない場合は処理を終了
16    if (!is_dir($dirPath)) {
17        return false;
18    }
19
20    // ディレクトリ内のアイテム(ファイル、サブディレクトリ)を取得
21    // scandirは '.' と '..' も返すため、これらは除外する
22    $items = array_diff(scandir($dirPath), ['.', '..']);
23
24    foreach ($items as $item) {
25        $itemPath = $dirPath . DIRECTORY_SEPARATOR . $item;
26        
27        // アイテムがディレクトリの場合は再帰的にこの関数を呼び出す
28        if (is_dir($itemPath)) {
29            if (!deleteDirectoryRecursively($itemPath)) {
30                return false; // サブディレクトリの削除に失敗した場合
31            }
32        } else {
33            // アイテムがファイルの場合はunlinkで削除
34            if (!unlink($itemPath)) {
35                return false; // ファイルの削除に失敗した場合
36            }
37        }
38    }
39
40    // 中身が空になったディレクトリをrmdirで削除
41    return rmdir($dirPath);
42}
43
44// --- 以下、サンプルコードの実行部分 ---
45
46// 1. テスト用のディレクトリとファイルを作成
47$targetDir = __DIR__ . '/test_directory';
48if (!file_exists($targetDir)) {
49    mkdir($targetDir, 0777, true);
50    mkdir($targetDir . '/sub_dir', 0777, true);
51    file_put_contents($targetDir . '/file1.txt', 'test');
52    file_put_contents($targetDir . '/sub_dir/file2.txt', 'test');
53    echo "テスト用のディレクトリを作成しました: " . $targetDir . PHP_EOL;
54}
55
56// 2. 作成した関数を呼び出して、ディレクトリをファイルごと削除
57echo "ディレクトリを削除します..." . PHP_EOL;
58if (deleteDirectoryRecursively($targetDir)) {
59    echo "ディレクトリの削除に成功しました。" . PHP_EOL;
60} else {
61    echo "ディレクトリの削除に失敗しました。" . PHP_EOL;
62}
63
64// 3. 削除されたかを確認
65if (!file_exists($targetDir)) {
66    echo "ディレクトリが存在しないことを確認しました。" . PHP_EOL;
67} else {
68    echo "ディレクトリがまだ存在します。" . PHP_EOL;
69}

PHPのrmdir関数は、指定されたパスのディレクトリを削除するために使用されます。引数として削除したいディレクトリのパスを文字列で受け取り、処理が成功すればtrueを、失敗すればfalseをブール値で返します。この関数の重要な点は、削除対象のディレクトリが完全に空である場合にのみ機能するという制約があることです。

提供されたサンプルコードでは、このrmdir関数の制約を補完し、ファイルやサブディレクトリを含むディレクトリ全体を再帰的に削除するdeleteDirectoryRecursively関数が実装されています。このカスタム関数は、まず指定されたディレクトリの中身をscandirで取得し、ファイルであればunlink関数で削除します。サブディレクトリが見つかった場合は、自身を再帰的に呼び出してそのサブディレクトリの中身を先に空にします。このようにして、ディレクトリ内のすべてのファイルとサブディレクトリを削除し終えてディレクトリが空になった後、最後にrmdir関数を使ってそのディレクトリ自体を削除します。これにより、rmdir単体ではできない、中身のあるディレクトリも安全かつまとめて削除する処理を実現しています。

PHPのrmdir関数は、ファイルやサブディレクトリを含まない空のディレクトリしか削除できません。サンプルコードは、この制約を回避するため、まずディレクトリ内のファイルやサブディレクトリを再帰的にすべて削除し、その後にrmdirで空になったディレクトリ自体を削除する処理を実装しています。このような再帰的な削除は非常に強力で、誤ったパスを指定すると重要なデータが完全に消えてしまう危険性がありますので、実行前には必ず削除対象パスを厳重に確認してください。また、削除処理が失敗した場合に備え、サンプルコードのように適切なエラーチェックを行うことが安全な利用には不可欠です。

PHPでディレクトリを強制削除する

1<?php
2
3/**
4 * 指定されたディレクトリとその内容を強制的に削除します。
5 * ディレクトリが空でなくても、その中のファイルやサブディレクトリを再帰的に削除し、
6 * 最終的に空になったディレクトリを削除します。
7 *
8 * rmdir() 関数は空のディレクトリしか削除できないため、
9 * この関数はその制約を克服し「強制的な削除」を実現します。
10 *
11 * @param string $directory 削除するディレクトリのパス
12 * @return bool 削除が成功した場合は true、失敗した場合は false
13 */
14function removeDirectoryRecursive(string $directory): bool
15{
16    // ディレクトリが存在しない場合、削除済みとみなし成功を返します
17    if (!is_dir($directory)) {
18        return true;
19    }
20
21    // ディレクトリの内容を読み込みます
22    $items = scandir($directory);
23
24    // ディレクトリの読み込みに失敗した場合
25    if ($items === false) {
26        error_log("Failed to read directory: " . $directory);
27        return false;
28    }
29
30    foreach ($items as $item) {
31        // カレントディレクトリと親ディレクトリへの参照はスキップします
32        if ($item === '.' || $item === '..') {
33            continue;
34        }
35
36        $path = $directory . DIRECTORY_SEPARATOR . $item;
37
38        if (is_dir($path)) {
39            // サブディレクトリの場合、この関数を再帰的に呼び出して削除します
40            if (!removeDirectoryRecursive($path)) {
41                error_log("Failed to remove subdirectory: " . $path);
42                return false; // サブディレクトリの削除に失敗
43            }
44        } else {
45            // ファイルの場合、unlink() 関数で削除します
46            if (!unlink($path)) {
47                error_log("Failed to remove file: " . $path);
48                return false; // ファイルの削除に失敗
49            }
50        }
51    }
52
53    // すべてのコンテンツが削除された後、空になったディレクトリを rmdir() 関数で削除します
54    // rmdir() は空のディレクトリのみ削除できます
55    if (!rmdir($directory)) {
56        error_log("Failed to remove empty directory: " . $directory);
57        return false; // 空になったディレクトリの削除に失敗
58    }
59
60    return true; // 成功
61}
62
63// --- サンプルコードの実行例 ---
64
65// テスト用のディレクトリを作成します
66$testBaseDir = 'test_forced_removal';
67$subDir1 = $testBaseDir . DIRECTORY_SEPARATOR . 'subdir1';
68$subDir2 = $subDir1 . DIRECTORY_SEPARATOR . 'subdir2';
69
70// 存在しない場合はディレクトリを作成
71if (!is_dir($testBaseDir)) {
72    mkdir($testBaseDir);
73}
74if (!is_dir($subDir1)) {
75    mkdir($subDir1);
76}
77if (!is_dir($subDir2)) {
78    mkdir($subDir2);
79}
80
81// テスト用のファイルを作成します
82file_put_contents($testBaseDir . DIRECTORY_SEPARATOR . 'file_in_root.txt', 'Root file content.');
83file_put_contents($subDir1 . DIRECTORY_SEPARATOR . 'file_in_subdir1.txt', 'Subdir1 file content.');
84file_put_contents($subDir2 . DIRECTORY_SEPARATOR . 'file_in_subdir2.txt', 'Subdir2 file content.');
85
86echo "テストディレクトリ構造を生成しました: " . realpath($testBaseDir) . "\n";
87echo "このディレクトリと内容を強制削除します。\n";
88
89// removeDirectoryRecursive() 関数を呼び出して強制削除を実行します
90if (removeDirectoryRecursive($testBaseDir)) {
91    echo "ディレクトリ '{$testBaseDir}' とその内容を正常に強制削除しました。\n";
92} else {
93    echo "ディレクトリ '{$testBaseDir}' の強制削除に失敗しました。\n";
94}
95
96// 削除後にディレクトリが存在しないことを確認します
97if (!is_dir($testBaseDir)) {
98    echo "検証: ディレクトリ '{$testBaseDir}' は現在存在しません。\n";
99} else {
100    echo "検証: エラー!ディレクトリ '{$testBaseDir}' がまだ存在します。\n";
101}
102

PHPのrmdir関数は、指定された「空の」ディレクトリを削除するために使用されます。この関数は、削除したいディレクトリのパスを文字列として受け取り、成功した場合はtrue、失敗した場合はfalseを返します。しかし、rmdir関数はディレクトリ内にファイルやサブディレクトリが存在すると削除できないという制約があります。システム運用において、内容の有無にかかわらずディレクトリを強制的に削除したい場面があるため、この制約を克服するカスタム関数が必要となります。

提供されたサンプルコードでは、removeDirectoryRecursiveという関数がその「強制削除」を実現しています。この関数は、指定されたディレクトリとその内容を再帰的に削除します。具体的には、まずディレクトリ内のファイルはunlink関数で、サブディレクトリは自身を再帰的に呼び出すことで削除し、最終的に空になったディレクトリをrmdir関数で削除します。removeDirectoryRecursive関数も、削除するディレクトリのパスを文字列で引数に取り、削除が成功した場合はtrue、失敗した場合はfalseを戻り値として返します。このような強力な削除機能を利用する際は、誤って重要なファイルを削除しないよう、十分な注意が必要です。

このサンプルコードは、PHPのrmdir関数が空のディレクトリしか削除できない制約を克服し、指定されたディレクトリとその中の全てのファイル・サブディレクトリを再帰的に強制削除します。一度削除すると元に戻せないため、実行パスの指定には細心の注意を払ってください。サーバーの重要なシステムディレクトリなどを誤って指定すると、システムに重大な損傷を与える可能性があります。本番環境で利用する際は、削除対象のパスがユーザーからの入力である場合、必ず適切なバリデーションを行い、意図しない削除を防ぐ仕組みを実装することが不可欠です。また、Webサーバーの実行ユーザーに適切な権限が付与されているか確認し、必要最小限の権限に留めるよう管理してください。深く複雑なディレクトリ構造の場合、PHPの実行時間やメモリ制限に注意が必要です。

関連コンテンツ

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