【PHP8.x】RecursiveDirectoryIterator::getPerms()メソッドの使い方
getPermsメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
getPermsメソッドは、RecursiveDirectoryIteratorクラスに属し、指定されたファイルやディレクトリのアクセス権限(パーミッション)を取得するために使用されるメソッドです。
RecursiveDirectoryIteratorクラスは、ディレクトリ構造を再帰的に走査する際に利用され、その過程で見つかる各ファイルやディレクトリのエントリに対して、このメソッドを呼び出すことができます。
このメソッドが返す値は整数型であり、ファイルシステムのパーミッション情報を数値として表現します。例えば、LinuxなどのUnix系OSでchmodコマンドによって設定される0755のような8進数表記を思い浮かべると理解しやすいでしょう。この数値は、ファイルの所有者、グループ、その他のユーザーに対して、読み取り、書き込み、実行のどの操作が許可されているかを示します。
注意点として、getPermsメソッドが返す整数値には、純粋なアクセス権限だけでなく、そのエントリが通常のファイルであるか、ディレクトリであるか、あるいはシンボリックリンクであるかといったファイルタイプに関する情報も含まれています。したがって、もし純粋なアクセス権限のみが必要な場合は、ビットマスク(例えば0777)を用いてファイルタイプ情報を取り除く必要がある場合があります。
このメソッドは、アプリケーションがファイルやディレクトリに対する操作を行う前に、適切な権限を持っているかを確認したり、セキュリティ上の理由から特定の権限を持つファイルにのみアクセスを許可するロジックを実装したりする際に非常に有用です。システムエンジニアにとって、ファイルシステムの挙動やセキュリティを理解する上で重要なツールの一つとなります。
構文(syntax)
1<?php 2 3$iterator = new RecursiveDirectoryIterator(__DIR__); 4$recursiveIterator = new RecursiveIteratorIterator($iterator); 5 6foreach ($recursiveIterator as $fileInfo) { 7 $permissions = $fileInfo->getPerms(); 8}
引数(parameters)
引数なし
引数はありません
戻り値(return)
int
RecursiveDirectoryIterator::getPerms() は、現在のファイルまたはディレクトリのエントリのパーミッション(アクセス権)を整数値で返します。
サンプルコード
PHP RecursiveDirectoryIterator::getPerms()でパーミッション取得
1<?php 2 3/** 4 * RecursiveDirectoryIterator::getPerms() メソッドの使用例。 5 * ファイルやディレクトリのパーミッション(権限)を取得する方法を示します。 6 * 7 * このスクリプトは一時ディレクトリを作成し、その中にダミーファイルとディレクトリを配置します。 8 * その後、RecursiveDirectoryIterator を使用してそれらを走査し、 9 * 各要素のパーミッションを RecursiveDirectoryIterator::getPerms() で取得し表示します。 10 * 最後に、作成した一時ディレクトリをクリーンアップします。 11 */ 12 13/** 14 * テスト用の一時ディレクトリを作成し、ダミーのファイルとディレクトリを配置します。 15 * 16 * @return string 作成された一時ディレクトリのパス 17 */ 18function setupTestDirectory(): string 19{ 20 // ユニークな名前で一時ディレクトリを作成 21 $tempDir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'php_perms_example_' . uniqid(); 22 if (!mkdir($tempDir, 0777, true)) { 23 exit("エラー: 一時ディレクトリの作成に失敗しました: " . $tempDir); 24 } 25 echo "一時ディレクトリを作成しました: " . $tempDir . PHP_EOL; 26 27 // ダミーファイルを作成し、パーミッションを設定 28 file_put_contents($tempDir . DIRECTORY_SEPARATOR . 'file_private.txt', 'このファイルは所有者のみが読み書きできます。'); 29 chmod($tempDir . DIRECTORY_SEPARATOR . 'file_private.txt', 0600); // rwx = 110 000 000 => 600 30 31 file_put_contents($tempDir . DIRECTORY_SEPARATOR . 'file_public.txt', 'このファイルは誰でも読み書きできます。'); 32 chmod($tempDir . DIRECTORY_SEPARATOR . 'file_public.txt', 0666); // rwx = 110 110 110 => 666 33 34 // サブディレクトリを作成し、パーミッションを設定 35 $subDir = $tempDir . DIRECTORY_SEPARATOR . 'sub_dir'; 36 mkdir($subDir, 0755); // rwx = 111 101 101 => 755 37 echo "サブディレクトリを作成しました: " . $subDir . PHP_EOL; 38 39 file_put_contents($subDir . DIRECTORY_SEPARATOR . 'nested_file.txt', 'サブディレクトリ内のファイル。'); 40 chmod($subDir . DIRECTORY_SEPARATOR . 'nested_file.txt', 0640); // rwx = 110 100 000 => 640 41 42 return $tempDir; 43} 44 45/** 46 * 指定されたディレクトリとその内容を再帰的に削除します。 47 * 48 * @param string $dir 削除するディレクトリのパス 49 */ 50function cleanupTestDirectory(string $dir): void 51{ 52 if (!is_dir($dir)) { 53 return; 54 } 55 56 // RecursiveIteratorIterator を使用してディレクトリ内のすべての要素を走査し、削除 57 // CHILD_FIRST は、子要素を先に削除してから親ディレクトリを削除することを意味します 58 $files = new RecursiveIteratorIterator( 59 new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS), 60 RecursiveIteratorIterator::CHILD_FIRST 61 ); 62 63 foreach ($files as $fileinfo) { 64 $realPath = $fileinfo->getRealPath(); 65 if ($fileinfo->isDir()) { 66 rmdir($realPath); 67 } else { 68 unlink($realPath); 69 } 70 } 71 rmdir($dir); 72 echo "一時ディレクトリを削除しました: " . $dir . PHP_EOL; 73} 74 75// スクリプトのメイン処理 76$testDir = ''; // 初期化 77 78try { 79 // 1. テスト用のディレクトリとファイルを準備 80 $testDir = setupTestDirectory(); 81 82 echo PHP_EOL . "--- ファイルとディレクトリのパーミッション ---" . PHP_EOL; 83 84 // 2. RecursiveDirectoryIterator を作成し、指定されたディレクトリを走査します。 85 // RecursiveDirectoryIterator::SKIP_DOTS は、"." と ".." エントリをスキップするために使用します。 86 $directoryIterator = new RecursiveDirectoryIterator($testDir, RecursiveDirectoryIterator::SKIP_DOTS); 87 88 // 3. RecursiveIteratorIterator を作成し、ディレクトリを再帰的に走査します。 89 // RecursiveIteratorIterator::SELF_FIRST は、ディレクトリ自身を先に、 90 // その後にその内容を走査することを意味します。 91 $iterator = new RecursiveIteratorIterator($directoryIterator, RecursiveIteratorIterator::SELF_FIRST); 92 93 // 4. 各ファイルまたはディレクトリをループ処理 94 foreach ($iterator as $fileInfo) { 95 // RecursiveDirectoryIterator の要素からパス情報(SplFileInfoオブジェクト)を取得 96 // getPerms() メソッドは、ファイルまたはディレクトリのパーミッションを整数値で返します。 97 // 例: 0644 は 420、0755 は 493 という整数値になります。 98 $perms = $fileInfo->getPerms(); 99 100 // 取得した整数値パーミッションを8進数形式に変換して表示します。 101 // 8進数形式(例: 0755, 0644)は、UNIXライクなシステムでファイル権限を表す一般的な形式です。 102 // sprintf('%o', $perms) を使用することで、この変換が行われます。 103 echo sprintf( 104 "%s: %s (絶対パス: %s, パーミッション: %o)", 105 $fileInfo->isDir() ? "ディレクトリ" : "ファイル", // ディレクトリかファイルかを判別 106 $fileInfo->getFilename(), // ファイル/ディレクトリ名 107 $fileInfo->getRealPath(), // 絶対パス 108 $perms // 8進数形式に変換されたパーミッション 109 ) . PHP_EOL; 110 } 111} catch (UnexpectedValueException $e) { 112 // 無効なパスが指定された場合などに発生するエラーをキャッチ 113 echo "エラー: ディレクトリの読み込みに失敗しました: " . $e->getMessage() . PHP_EOL; 114} catch (Exception $e) { 115 // その他の予期せぬエラーをキャッチ 116 echo "予期せぬエラーが発生しました: " . $e->getMessage() . PHP_EOL; 117} finally { 118 // スクリプトの実行が完了した後、必ず一時ディレクトリをクリーンアップ 119 if (!empty($testDir)) { 120 cleanupTestDirectory($testDir); 121 } 122} 123 124?>
RecursiveDirectoryIterator::getPerms()は、PHP 8で提供される拡張機能の一つで、ファイルやディレクトリのパーミッション(アクセス権限)を数値として取得するためのメソッドです。このメソッドは、RecursiveDirectoryIteratorクラスが生成するSplFileInfoオブジェクトに対して呼び出されます。引数はなく、ファイルまたはディレクトリのパーミッション情報を表す整数値を返します。取得した整数値は、UNIX系システムでよく使われる8進数形式(例:0755)に変換することで、人間が読みやすい形式で表示できます。サンプルコードでは、一時的に作成したディレクトリ構造を再帰的に走査し、各ファイルやサブディレクトリのパーミッションをgetPerms()で取得し、その結果を8進数に変換して出力しています。これにより、プログラムでファイルやディレクトリの権限を詳細に確認し、管理する際に役立ちます。
RecursiveDirectoryIterator::getPerms()は、ファイルやディレクトリのパーミッションを整数値で返します。取得されるパーミッションは整数値であり、一般的な8進数表記(例: 0755)とはそのままでは異なるため、表示の際はsprintf('%o', $perms)のように変換してください。この機能はUNIX系OSに特有の概念に基づくため、Windows環境では期待通りの結果が得られないことがあります。chmod関数でパーミッションを設定する際は、8進数として扱うには0755のように先頭に0を付ける必要があります。サンプルコードのように一時的なファイルシステム操作を行う際は、finallyブロックを活用して作成物を確実にクリーンアップし、エラーハンドリングを適切に行うことが安全な運用に繋がります。
PHP RecursiveDirectoryIteratorでパーミッションを取得する
1<?php 2 3/** 4 * RecursiveDirectoryIterator を使用して指定されたディレクトリ内の 5 * ファイルおよびサブディレクトリのパーミッションを取得し表示します。 6 * 7 * RecursiveDirectoryIterator クラスは、ファイルシステムを再帰的に走査するための 8 * イテレータを提供します。そのイテレータが返す SplFileInfo オブジェクトから 9 * getPerms() メソッドを呼び出すことで、ファイルやディレクトリのパーミッション 10 * (権限) を整数値で取得できます。 11 * 12 * この関数は、システムエンジニアがファイルやディレクトリのアクセス権限を確認・管理する際に役立ちます。 13 * 14 * @param string $path パーミッションを取得するディレクトリのパス 15 * @return void 16 */ 17function displayDirectoryPermissions(string $path): void 18{ 19 // 指定されたパスが存在し、かつディレクトリであることを確認 20 if (!is_dir($path)) { 21 echo "エラー: 指定されたディレクトリ '{$path}' が見つからないか、ディレクトリではありません。" . PHP_EOL; 22 return; 23 } 24 25 echo "--- ディレクトリ '{$path}' 内のアイテムのパーミッション ---" . PHP_EOL; 26 try { 27 // RecursiveDirectoryIterator を使用してディレクトリを再帰的に走査 28 // FilesystemIterator::SKIP_DOTS は . と .. をスキップするフラグ 29 $directoryIterator = new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS); 30 31 // RecursiveIteratorIterator を使用して、再帰的に全てのファイルとディレクトリをイテレート 32 // SELF_FIRST は、ディレクトリ自体を先に、その後に内容をイテレートする設定 33 $iterator = new RecursiveIteratorIterator($directoryIterator, RecursiveIteratorIterator::SELF_FIRST); 34 35 foreach ($iterator as $fileInfo) { 36 // SplFileInfo オブジェクトから getPerms() メソッドでパーミッションを取得 37 // 戻り値は整数値です (例: 33204は0o100644, 16877は0o040755 など) 38 $perms = $fileInfo->getPerms(); 39 40 // パーミッションの整数値から、通常使用される8進数表記 (例: 0o755) を抽出 41 // 0o777 はファイルシステムのパーミッションビットのみをマスクします。 42 $octalPerms = $perms & 0o777; 43 44 // ファイルタイプ (ファイルまたはディレクトリ) を表示 45 $type = $fileInfo->isDir() ? 'ディレクトリ' : 'ファイル'; 46 47 // 結果を整形して出力 48 echo sprintf( 49 "- %s (%s): 0o%o" . PHP_EOL, 50 $fileInfo->getPathname(), // アイテムのフルパス 51 $type, // アイテムのタイプ 52 $octalPerms // 8進数形式のパーミッション 53 ); 54 } 55 } catch (UnexpectedValueException $e) { 56 // 無効なディレクトリパスなどが指定された場合の例外処理 57 echo "エラー: ディレクトリの読み取り中に問題が発生しました - " . $e->getMessage() . PHP_EOL; 58 } 59} 60 61// --- サンプルコードの実行 --- 62// このコードを単体で動作させるために、一時的なテストディレクトリを作成します。 63$testDirPath = __DIR__ . '/_temp_test_perms_dir'; 64 65// テストディレクトリが存在しない場合は作成し、テストファイルを配置 66if (!file_exists($testDirPath)) { 67 mkdir($testDirPath, 0o777, true); // ディレクトリを再帰的に作成 (パーミッション0o777) 68 file_put_contents($testDirPath . '/example_file.txt', 'これはテストファイルです。'); 69 mkdir($testDirPath . '/sub_directory', 0o755); // サブディレクトリを作成 (パーミッション0o755) 70 file_put_contents($testDirPath . '/sub_directory/nested_file.txt', 'これはネストされたテストファイルです。'); 71 // PHPでパーミッションを変更する例 (オプション) 72 // chmod($testDirPath . '/example_file.txt', 0o644); 73} 74 75// 作成したテストディレクトリのパーミッションを表示する関数を呼び出し 76displayDirectoryPermissions($testDirPath); 77 78// 注意: 通常のウェブアプリケーションでは、直接ファイルシステムのパスを操作する前に 79// 適切なセキュリティチェックを行う必要があります。
RecursiveDirectoryIteratorクラスのgetPermsメソッドは、PHP 8で利用でき、指定されたファイルやディレクトリのパーミッション(アクセス権限)を整数値として取得します。このメソッドは、RecursiveDirectoryIteratorが提供するSplFileInfoオブジェクトから呼び出され、引数は必要ありません。戻り値はint型で、ファイルやディレクトリの属性情報を含む整数値です。
サンプルコードでは、RecursiveDirectoryIteratorとRecursiveIteratorIteratorを用いて、指定されたディレクトリとその配下のすべてのファイルやサブディレクトリを再帰的に走査します。走査によって得られる各ファイルやディレクトリ(SplFileInfoオブジェクト)に対し、getPerms()メソッドを呼び出してパーミッションを取得します。取得される整数値は、ビット演算子の&と8進数マスク0o777を使うことで、0o755のような一般的な8進数形式のパーミッションに変換して表示できます。この機能は、システムエンジニアがファイルやディレクトリのアクセス権限をプログラムで確認・管理する際に非常に有用です。
getPerms()メソッドは、ファイルやディレクトリのパーミッションを整数値で返します。この整数値には、ファイルタイプなどの情報も含まれているため、UNIX系OSでよく見かける0o755のような8進数表記で表示したい場合は、サンプルコードのようにビットマスク& 0o777を使用してパーミッション部分のみを抽出する必要があります。
RecursiveDirectoryIteratorは、指定されたディレクトリとその中のサブディレクトリを再帰的に走査するのに便利ですが、存在しないパスやアクセス権のないパスを指定するとUnexpectedValueExceptionが発生することがありますので、エラーハンドリングを適切に行ってください。
ファイルシステムの操作はセキュリティ上のリスクを伴います。特にユーザーからの入力に基づいてパスを操作する場合は、悪意のあるパスが指定されることによる「パスインジェクション」などの攻撃を防ぐため、常にパスの検証、サニタイズ、そして適切なアクセス権限のチェックを厳重に行ってください。