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

【PHP8.x】mkdir()関数の使い方

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

作成日: 更新日:

基本的な使い方

mkdir関数は、指定されたパスに新しいディレクトリ(フォルダ)を作成する関数です。この関数は、主にファイルシステム上で新しい格納場所をプログラムから動的に生成したい場合に使用されます。

最も基本的な使い方は、第一引数に作成したいディレクトリのパスを文字列で渡すことです。例えば、mkdir('new_folder'); と記述すると、スクリプトが実行されているカレントディレクトリに new_folder という名前のディレクトリが作成されます。

第二引数には、作成されるディレクトリのパーミッション(権限)を八進数で指定できます。デフォルト値は 0777 ですが、これはすべてのユーザーに読み書き実行の権限を与えるため、セキュリティ上の理由から、通常はより制限された 0755 などを指定することが推奨されます。このパーミッションは、システムのファイルモードマスク(umask)によっても影響を受ける点に注意が必要です。

第三引数 $recursivetrue を指定すると、作成したいディレクトリの親ディレクトリが存在しない場合でも、それらの親ディレクトリも同時に作成されます。この引数を false のままにすると、親ディレクトリが存在しない場合はエラーとなり、ディレクトリは作成されません。

mkdir関数は、ディレクトリの作成に成功した場合に true を、失敗した場合に false を返します。そのため、関数を実行した後は、戻り値を確認して処理の成否を判断することが重要です。既に同名のディレクトリが存在する場合や、指定されたパスへの書き込み権限がない場合など、様々な理由で作成に失敗する可能性があります。エラーメッセージはPHPの警告として出力されますが、falseの戻り値を受け取ることでプログラム的に失敗を検知し、適切にエラーハンドリングを行うことができます。

構文(syntax)

1mkdir("path/to/my/new/directory", 0755, true);

引数(parameters)

string $directory, int $permissions = 0777, bool $recursive = false, resource $context = null

  • string $directory: 作成するディレクトリのパスを指定する文字列
  • int $permissions = 0777: ディレクトリのパーミッション(権限)を整数で指定します。デフォルトは0777です。
  • bool $recursive = false: trueを指定すると、親ディレクトリが存在しない場合でも再帰的に作成します。デフォルトはfalseです。
  • resource $context = null: ストリームコンテキストを指定するリソースです。通常はnullで問題ありません。

戻り値(return)

bool

指定されたディレクトリを作成できなかった場合は false を返します。

サンプルコード

PHP mkdirエラー処理でディレクトリを作成する

1<?php
2
3/**
4 * 指定されたディレクトリを作成します。
5 * 成功または失敗の結果と、失敗時のエラー詳細メッセージを表示します。
6 *
7 * @param string $directoryPath 作成するディレクトリのパス。
8 * @param int $permissions ディレクトリのパーミッション(例: 0755)。
9 * @param bool $recursive 親ディレクトリが存在しない場合に再帰的に作成するかどうか。
10 * @return bool ディレクトリが正常に作成されたか、または既に存在していた場合は true。
11 *              作成に失敗した場合は false。
12 */
13function createDirectoryWithErrorHandler(
14    string $directoryPath,
15    int $permissions = 0755,
16    bool $recursive = true
17): bool {
18    // ディレクトリが既に存在するかチェックします。
19    // 既に存在する場合は、作成を試みずに成功とみなします。
20    if (is_dir($directoryPath)) {
21        echo "INFO: ディレクトリ '{$directoryPath}' は既に存在します。\n";
22        return true;
23    }
24
25    // mkdir関数を実行。@演算子でPHPが通常発行するE_WARNINGを抑制し、
26    // 戻り値で成否を判断するようにします。これにより、エラー処理をコード内で制御しやすくなります。
27    // WARNINGが抑制されても、error_get_last()でエラー情報を取得可能です。
28    if (@mkdir($directoryPath, $permissions, $recursive)) {
29        echo "SUCCESS: ディレクトリ '{$directoryPath}' を正常に作成しました。\n";
30        return true;
31    } else {
32        // mkdirが失敗した場合の処理
33        echo "ERROR: ディレクトリ '{$directoryPath}' の作成に失敗しました。\n";
34
35        // error_get_last() を使用して、直前のエラー情報を取得します。
36        // これにより、具体的な失敗原因(警告メッセージ)を知ることができます。
37        $error = error_get_last();
38        if ($error && $error['type'] === E_WARNING) {
39            echo "  詳細: " . $error['message'] . "\n";
40        }
41
42        echo "  考えられる一般的な原因:\n";
43        echo "  - 親ディレクトリが存在しない、かつ \$recursive が false に設定されている。\n";
44        echo "  - 実行ユーザーが、指定されたパスにディレクトリを作成する書き込み権限を持っていない。\n";
45        echo "  - 指定されたパス名が無効である(例: ファイルシステムで予約されている文字が含まれる)。\n";
46        echo "  - ディスク容量不足(稀なケース)。\n";
47        return false;
48    }
49}
50
51// --- サンプルコードの実行例 ---
52
53// 1. 正常にディレクトリを作成するケース
54echo "--- 実行例 1: 正常なディレクトリ作成 ---\n";
55$dir1 = 'example_dir_success';
56createDirectoryWithErrorHandler($dir1);
57// 後処理: 作成したディレクトリを削除して、スクリプトを繰り返し実行できるようにします。
58if (is_dir($dir1)) {
59    rmdir($dir1);
60    echo "  (後処理) ディレクトリ '{$dir1}' を削除しました。\n";
61}
62echo "\n";
63
64// 2. 既に存在するディレクトリを作成しようとするケース
65echo "--- 実行例 2: 既存ディレクトリの作成試行 ---\n";
66$dir2 = 'example_dir_existing';
67// 事前にディレクトリを作成しておく
68mkdir($dir2);
69echo "  (事前準備) ディレクトリ '{$dir2}' を作成しました。\n";
70createDirectoryWithErrorHandler($dir2);
71// 後処理
72if (is_dir($dir2)) {
73    rmdir($dir2);
74    echo "  (後処理) ディレクトリ '{$dir2}' を削除しました。\n";
75}
76echo "\n";
77
78// 3. 親ディレクトリが存在しない、かつ $recursive が false のため失敗するケース
79echo "--- 実行例 3: recursive=false での失敗 ---\n";
80$dir3 = 'non_existent_parent/example_dir_fail_recursive';
81createDirectoryWithErrorHandler($dir3, 0755, false); // recursiveをfalseに設定
82echo "\n";
83
84// 4. 権限がないため失敗する可能性のあるケース (説明のみ)
85echo "--- 実行例 4: 権限不足による失敗の可能性 ---\n";
86echo "  このケースは、実行環境の権限設定に大きく依存するため、具体的な失敗を確実に再現するコードは記述しません。\n";
87echo "  例: Linux/Unix系システムで '/root/some_protected_dir' のようなパスに一般ユーザーが作成を試みると失敗します。\n";
88echo "  その際、`error_get_last()`は「Permission denied」のようなメッセージを報告します。\n";
89// 実際に試す場合は、以下のようにコメントを外して、書き込み権限のないパスを指定してください。
90// $dir4 = '/root/example_dir_permission_denied'; // 通常のユーザーでは権限がない
91// createDirectoryWithErrorHandler($dir4);
92
93?>

PHPのmkdir関数は、指定したパスに新しいディレクトリを作成する機能を提供します。第一引数で作成するディレクトリのパスを文字列で指定し、第二引数でアクセス権限を数値(例: 0755)で設定します。第三引数$recursiveは、trueに設定すると指定パスの途中の親ディレクトリが存在しない場合でも再帰的に作成しますが、falseの場合は親ディレクトリがなければ作成に失敗します。関数はディレクトリの作成に成功するとtrue、失敗するとfalseを戻り値として返します。

サンプルコードでは、mkdir関数が失敗時に発生させる可能性のある警告(E_WARNING)を@演算子で抑制し、戻り値で成否を判断しています。これにより、PHPが自動的にエラーメッセージを表示するのを防ぎ、プログラム内でエラー処理を制御しやすくしています。さらに、error_get_last()関数を使うことで、抑制された警告も含め、直前に発生したエラーの詳細なメッセージを取得し、作成失敗の具体的な原因(例: 権限不足やパスの誤り)を特定して表示しています。この方法は、堅牢なディレクトリ作成処理を実装し、エラー発生時に詳細な情報を提供する上で非常に役立ちます。

このサンプルコードは、mkdir関数の利用において、いくつかの重要な注意点を示しています。まず、ディレクトリ作成前にis_dir()で存在を確認し、既に存在する場合の無用な警告を避けましょう。エラー処理では、@演算子で警告を抑制し、代わりにerror_get_last()で詳細なエラーメッセージを取得する方法は、問題発生時の原因究明に非常に役立ちますので、必ず適用してください。また、パーミッションは0755のような八進数で指定し、適切な権限設定がセキュリティ上不可欠です。$recursive引数をtrueに設定すれば、親ディレクトリが存在しない場合でも自動的に作成され、エラーを減らせます。さらに、PHPスクリプトを実行するユーザーが、指定パスに書き込み権限を持っているかを常に確認することが重要です。これらの点を守ることで、安全で堅牢なコードになります。

PHP mkdir でパーミッションを指定してディレクトリ作成する

1<?php
2
3// 作成するディレクトリのパスを定義します。
4$directoryPath = 'my_new_directory';
5$nestedDirectoryPath = 'temp_parent/temp_child/final_directory';
6
7// ディレクトリのパーミッションを8進数で定義します (例: 0755)。
8// 0755 は通常、所有者に読み書き実行権限、グループとその他に読み込みと実行権限を与えます。
9// (例: 0755 -> 所有者:rwx, グループ:r-x, その他:r-x)
10$permissions = 0755;
11
12echo "--- 単一ディレクトリの作成 (パーミッション指定) ---\n";
13
14// mkdir関数を使用してディレクトリを作成します。
15// 第1引数: 作成するディレクトリのパス
16// 第2引数: パーミッション (8進数)
17if (mkdir($directoryPath, $permissions)) {
18    echo "ディレクトリ '{$directoryPath}' を作成しました。\n";
19    // 作成されたディレクトリの実際のパーミッションを表示します (fileperms() & 0777 でパーミッション部分のみ取得)。
20    echo "実際のパーミッション: " . decoct(fileperms($directoryPath) & 0777) . "\n";
21} else {
22    echo "ディレクトリ '{$directoryPath}' の作成に失敗しました。既に存在するか、権限が不足している可能性があります。\n";
23}
24
25echo "\n--- 複数階層ディレクトリの作成 (再帰的、パーミッション指定) ---\n";
26
27// 第3引数を true にすると、存在しない親ディレクトリも自動的に作成されます (再帰的)。
28// PHP 8 では、親ディレクトリにも指定されたパーミッションが適用されます。
29if (mkdir($nestedDirectoryPath, $permissions, true)) {
30    echo "複数階層ディレクトリ '{$nestedDirectoryPath}' を作成しました。\n";
31    echo "実際のパーミッション: " . decoct(fileperms($nestedDirectoryPath) & 0777) . "\n";
32} else {
33    echo "複数階層ディレクトリ '{$nestedDirectoryPath}' の作成に失敗しました。\n";
34}
35
36// 注意: このスクリプトを実行後、作成されたディレクトリは手動で削除してください。
37
38?>

PHPのmkdir関数は、新しいディレクトリを作成するために使用します。この関数は、指定されたパスにディレクトリを生成し、ファイルシステムの構造をプログラムから操作できる便利な機能を提供します。

第一引数$directoryには、作成したいディレクトリのパスを文字列で指定します。第二引数$permissionsでは、そのディレクトリに与えるアクセス権限を8進数で指定します。例えば0755という値は、ディレクトリの所有者には読み込み・書き込み・実行の全ての権限を与え、グループとその他のユーザーには読み込みと実行権限を与えることを意味します。これにより、セキュリティとアクセス制御を適切に行うことができます。

第三引数$recursivetrueに設定すると、作成しようとしているディレクトリの親ディレクトリが存在しない場合でも、それらを自動的に作成しながら階層的にディレクトリを生成します。PHP 8以降では、この再帰的な作成時に親ディレクトリにも指定された$permissionsが適用されます。関数が正常にディレクトリを作成できた場合はtrueを、失敗した場合はfalseを返します。失敗の主な原因としては、指定されたパスが既に存在しているか、ディレクトリを作成する権限がないなどが挙げられます。

サンプルコードでは、my_new_directoryという単一のディレクトリをパーミッション0755で作成する例と、temp_parent/temp_child/final_directoryという複数階層のディレクトリを再帰的に作成する例を示しています。fileperms()関数とdecoct()関数を組み合わせることで、作成されたディレクトリの実際のパーミッションを8進数で確認できます。

PHPのmkdir関数でディレクトリを作成する際は、パーミッションを8進数で指定し、セキュリティのため安易に0777は避け、適切な権限を設定してください。mkdirは成功時にtrue、失敗時にfalseを返すため、必ず戻り値をチェックし、エラー処理を行ってください。recursive引数をtrueにすると、存在しない親ディレクトリも同時に作成されます。PHP 8以降では、再帰的作成時に親ディレクトリにも指定パーミッションが適用されます。システムのumask設定により、指定パーミッションが期待通りに適用されない場合があるため、fileperms()で実際のパーミッションを確認すると良いでしょう。

PHPでmkdirによるパーミッションエラーを解決する

1<?php
2
3/**
4 * 指定されたパスにディレクトリを作成します。
5 * `mkdir`関数の基本的な使い方、パーミッション設定、およびエラーハンドリングを示します。
6 * 特に「permission denied」のような一般的なファイルシステムエラーの診断に役立ちます。
7 *
8 * @param string $directoryPath 作成するディレクトリのパス。
9 * @param int $permissions ディレクトリのパーミッション (例: 0755)。
10 *                         PHPでは8進数表記 (`0755`) が一般的です。
11 *                         実際のパーミッションはシステムのumask設定によって最終決定されます。
12 *                         `0755` は所有者には読み書き実行、グループとその他には読み込み実行を許可します。
13 * @param bool $recursive `true`の場合、親ディレクトリが存在しない場合にそれらも同時に作成します。
14 * @return bool ディレクトリが正常に作成されたか、既に存在していた場合は`true`、失敗した場合は`false`を返します。
15 */
16function createDirectory(string $directoryPath, int $permissions = 0755, bool $recursive = true): bool
17{
18    // ディレクトリが既に存在するか確認します。
19    if (is_dir($directoryPath)) {
20        echo "ℹ️  ディレクトリ '{$directoryPath}' は既に存在します。\n";
21        return true; // 既に存在する場合は成功とみなします。
22    }
23
24    echo "Attempting to create directory: '{$directoryPath}' with permissions " . decoct($permissions) . "...\n";
25
26    // `mkdir`関数を呼び出し、結果をチェックします。
27    // `@`演算子で`mkdir`が生成するPHP Warningを抑制し、`error_get_last()`で詳細なエラー情報を捕捉します。
28    if (@mkdir($directoryPath, $permissions, $recursive)) {
29        echo "✅ ディレクトリ '{$directoryPath}' をパーミッション " . decoct($permissions) . " で正常に作成しました。\n";
30        return true;
31    } else {
32        // `mkdir`が失敗した場合、直前のエラー情報を取得します。
33        $error = error_get_last();
34        $errorMessage = $error['message'] ?? '不明なエラーが発生しました。';
35
36        echo "❌ ディレクトリ '{$directoryPath}' の作成に失敗しました。\n";
37        echo "   エラーメッセージ: " . $errorMessage . "\n";
38        echo "   特に 'Permission denied' (パーミッション拒否) の場合、以下の原因が考えられます:\n";
39        echo "     - スクリプトが親ディレクトリへの書き込み権限を持っていない。\n";
40        echo "     - 指定されたパスに、同名のファイルが既に存在している。\n";
41        echo "     - `$recursive` が `false` であり、かつ親ディレクトリが存在しない。\n";
42        // その他、ディスク容量不足、パスが長すぎるなどの可能性も考えられます。
43        return false;
44    }
45}
46
47// --- 使用例 ---
48
49// 1. スクリプトが実行されているディレクトリに新しいディレクトリを作成します。
50//    通常、この操作は成功するはずです。
51$targetDir1 = __DIR__ . '/my_app_data';
52createDirectory($targetDir1, 0755, true);
53
54echo "\n";
55
56// 2. 親ディレクトリが存在しない場合に再帰的に作成する例。
57//    これも通常は成功するはずです。
58$targetDir2 = __DIR__ . '/logs/daily/2023-10-27';
59createDirectory($targetDir2, 0700, true);
60
61echo "\n";
62
63// 3. 失敗する可能性のあるシナリオの例:
64//    - 既に存在するファイルをディレクトリとして作成しようとすると、エラーが発生します。
65//      この場合、`error_get_last()` は 'File exists' のようなメッセージを捕捉します。
66$existingFile = __DIR__ . '/config.ini';
67if (!file_exists($existingFile)) {
68    file_put_contents($existingFile, 'setting=value');
69    echo "ℹ️  テストファイル '{$existingFile}' を作成しました。\n";
70}
71echo "\n--- 既存のファイルをディレクトリとして作成しようとする場合 ---\n";
72createDirectory($existingFile, 0755, true);
73
74// 注意: 'Permission denied' エラーを意図的に再現するには、
75// このPHPスクリプトの実行ユーザーが書き込み権限を持たないパス (例: `/root/new_dir`) を
76// 指定する必要があります。しかし、このサンプルコードは様々な環境で単体動作するため、
77// 環境依存の絶対パスは避けています。`error_get_last()` を利用することで、
78// 実際に`Permission denied`が発生した場合でもその詳細なエラーメッセージを捕捉し、表示できます。
79
80// 後処理: サンプルコードの再実行を容易にするため、作成したディレクトリとファイルを削除します。
81// 実際のアプリケーションでは、このような一時ファイルのクリーンアップは、
82// 独自のライフサイクル管理で行われることが一般的です。
83if (is_dir($targetDir1)) {
84    rmdir($targetDir1);
85}
86if (is_dir($targetDir2)) {
87    rmdir($targetDir2);
88    rmdir(dirname($targetDir2)); // logs/daily
89    rmdir(dirname(dirname($targetDir2))); // logs
90}
91if (file_exists($existingFile)) {
92    unlink($existingFile);
93}

PHPのmkdir関数は、指定されたパスに新しいディレクトリを作成するために使用されます。この関数は、最初の引数$directoryに作成したいディレクトリのパスを文字列で受け取ります。

次に、$permissions引数で作成するディレクトリのアクセス権限を数値で設定します。PHPでは0755のような8進数表記が一般的で、これは所有者には読み書き実行、グループとその他には読み込みと実行を許可する設定です。実際のパーミッションはシステムのumask設定の影響を受けます。

3番目の引数$recursivetrueに設定すると、作成しようとしているディレクトリの親ディレクトリが存在しない場合でも、それらを自動的に作成してくれます。この機能は、複雑なディレクトリ階層を一度に構築する際に非常に便利です。

mkdir関数は、ディレクトリの作成に成功すればtrueを、失敗すればfalseをブール値として返します。サンプルコードでは、エラー発生時にPHP Warningを抑制しつつ、error_get_last()関数を用いて詳細なエラーメッセージを捕捉しています。これにより、ディレクトリ作成失敗の原因を特定しやすくなります。

特に「Permission denied」(パーミッション拒否)のエラーは、スクリプトを実行しているユーザーが親ディレクトリへの書き込み権限を持っていない場合や、指定されたパスに同名のファイルが既に存在する場合、あるいは$recursivefalseで親ディレクトリが存在しない場合に発生しやすいです。これらのエラーメッセージを適切に確認し対処することで、システム運用のトラブルシューティングに役立てることができます。

PHPのmkdir関数では、パーミッションは0755のような8進数で指定します。この値はシステムのumask設定によって最終的に調整されるため、意図しないパーミッションになる可能性を考慮してください。親ディレクトリが存在しない場合はrecursive引数をtrueに設定すると自動的に作成されます。ディレクトリ作成が失敗した場合、特に「Permission denied」は、スクリプトが親ディレクトリへの書き込み権限がないか、指定パスに同名のファイルが既に存在することが主な原因です。エラーの詳細を捕捉するためには、@演算子とerror_get_last()を併用すると良いでしょう。また、is_dir()で事前に存在を確認することで、エラーを未然に防ぎ、処理をスムーズに進めることができます。

PHP mkdir 再帰的ディレクトリ作成

1<?php
2
3/**
4 * 指定されたパスにディレクトリを再帰的に作成します。
5 *
6 * @param string $path 作成するディレクトリのパス。複数の階層を持つ場合でも動作します。
7 * @return bool ディレクトリの作成に成功した場合 true、失敗した場合 false を返します。
8 */
9function createRecursiveDirectory(string $path): bool
10{
11    // パーミッションを0777(全ユーザーに読み書き実行の権限)に設定し、
12    // 第3引数を true にすることで、パス中の存在しない親ディレクトリも全て作成します。
13    // この true が「再帰的」な作成を意味します。
14    if (mkdir($path, 0777, true)) {
15        echo "ディレクトリ '{$path}' を再帰的に作成しました。\n";
16        return true;
17    } else {
18        echo "ディレクトリ '{$path}' の作成に失敗しました。\n";
19        // 失敗の原因は、既にディレクトリが存在する場合、または権限がない場合などが考えられます。
20        return false;
21    }
22}
23
24// 使用例:
25// プロジェクトルートに 'data/uploads/images/2023/10' というディレクトリ構造を作成します。
26// 'data', 'data/uploads', 'data/uploads/images', 'data/uploads/images/2023'
27// の全てが存在しなくても、この関数が再帰的に作成します。
28$directoryToCreate = 'my_app_data/uploads/images/2023/10';
29
30createRecursiveDirectory($directoryToCreate);
31
32// 既に存在するディレクトリを再度作成しようとすると失敗しますが、エラーは発生しません。
33// しかし、この例では成功メッセージが表示されるため、実際にディレクトリが作成されたか確認してください。
34// `mkdir`関数はディレクトリが既に存在する場合に失敗(falseを返す)しますが、PHP警告はデフォルトでは出力されません。
35
36// テスト後に作成したディレクトリを削除する場合は、別途処理が必要です。
37// 例: rmdir($directoryToCreate); // これは一番末端の空のディレクトリしか削除できません
38// 深い階層をまとめて削除するには、より複雑な処理(再帰的な削除関数など)が必要になります。
39
40?>

PHPのmkdir関数は、新しいディレクトリを作成するために使用される機能です。第一引数$directoryには、作成したいディレクトリのパスを文字列で指定します。この関数の特に重要な特徴は、第三引数$recursivetrueに設定することで、「再帰的」なディレクトリ作成が可能になる点です。通常、mkdirは指定されたディレクトリの親ディレクトリが存在しないと失敗しますが、$recursivetrueにすると、指定されたパスに含まれる存在しない親ディレクトリも全て自動的に作成してくれます。これは、例えば「data/uploads/images/2023/10」のような複数の階層を持つディレクトリ構造を一度に作成したい場合に非常に便利です。

第二引数$permissionsには、作成されるディレクトリのアクセス権限を数値で指定し、デフォルトは0777(全ユーザーに読み書き実行の権限)です。戻り値はbool型で、ディレクトリの作成に成功すればtrue、失敗すればfalseを返します。失敗の主な原因としては、指定されたパスに既に同じ名前のディレクトリやファイルが存在する場合、または権限不足などが考えられます。サンプルコードでは、my_app_data/uploads/images/2023/10という多階層のディレクトリを、$recursive引数をtrueにすることで一括して作成しています。これにより、途中のディレクトリが存在しない場合でも、手間なく目的のディレクトリ構造を構築できます。

mkdir関数の第3引数をtrueにすることで、存在しない親ディレクトリもまとめて作成できます。これが「再帰的」な作成を意味します。第2引数の0777は全ユーザーに読み書き実行を許可する権限ですが、セキュリティを考慮し、本番環境ではより適切な権限設定を検討してください。指定したディレクトリが既に存在する場合、mkdirfalseを返し作成に失敗しますが、PHPの警告は通常表示されません。そのため、関数の戻り値で必ず作成の成否を確認することが重要です。また、作成したディレクトリを削除するrmdir関数は、空のディレクトリしか削除できませんので、深い階層をまとめて削除するには、別途再帰的な削除処理が必要になります。

関連コンテンツ

関連プログラミング言語