【PHP8.x】GlobIterator::isReadable()メソッドの使い方
isReadableメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
isReadableメソッドはGlobIteratorクラスにおいて、現在の要素(ファイルまたはディレクトリ)が読み取り可能であるかどうかを判定するために使用されるメソッドです。
PHPのGlobIteratorクラスは、指定されたパターンに一致するファイルやディレクトリを反復処理する際に利用されるイテレータです。このisReadableメソッドは、イテレータが現在指しているファイルまたはディレクトリに対して、現在のプログラムが読み取り権限を持っているかどうかを確認する役割を担います。
具体的には、対象のファイルやディレクトリが読み取り可能であればTRUEを返し、読み取り権限がない、あるいは何らかの理由でアクセスできない場合はFALSEを返します。例えば、アプリケーションがログファイルを読み込む前や、ユーザーがアップロードした設定ファイルを処理する前に、対象のファイルが存在し、かつ読み取り権限があるかを確認する際に非常に有用です。これにより、存在しないファイルやアクセス権のないファイルを無理に読み込もうとすることによるエラーを未然に防ぎ、より堅牢で安全なファイル操作を実装することが可能になります。ファイルシステム上のリソースにアクセスする前にそのリソースの読み取り可能性を事前にチェックすることで、予期せぬエラーやセキュリティ上の問題を回避できます。
構文(syntax)
1<?php 2$iterator = new GlobIterator('.'); 3 4if ($iterator->valid()) { 5 $isReadable = $iterator->isReadable(); 6 var_dump($isReadable); 7}
引数(parameters)
引数なし
引数はありません
戻り値(return)
bool
指定されたGlobIterator::isReadableメソッドは、現在のイテレータが指すファイルまたはディレクトリが読み取り可能であるかどうかを示すブール値(trueまたはfalse)を返します。
サンプルコード
PHP GlobIterator::isReadable() でファイル読み取り確認
1<?php 2 3// GlobIterator::isReadable() メソッドの使用例 4// このメソッドは、GlobIteratorが現在指しているファイルやディレクトリが読み取り可能かどうかを調べます。 5// 戻り値は真偽値 (true/false) です。 6 7// ---------------------------------------------------------------------- 8// 1. テスト環境の準備 9// このスクリプトが単体で動作するように、一時的なディレクトリとテストファイルを作成します。 10// ---------------------------------------------------------------------- 11// スクリプトと同じディレクトリ内に一時ディレクトリを作成します。 12$tempDir = __DIR__ . DIRECTORY_SEPARATOR . 'php_glob_test_dir'; 13if (!is_dir($tempDir)) { 14 mkdir($tempDir); 15 echo "一時ディレクトリを作成しました: " . $tempDir . "\n"; 16} 17 18// 読み取り可能なテストファイルを作成します。 19$testFile1 = $tempDir . DIRECTORY_SEPARATOR . 'document1.txt'; 20file_put_contents($testFile1, 'これはテストファイル1の内容です。'); 21echo "テストファイルを作成しました: " . $testFile1 . "\n"; 22 23// 別の読み取り可能なテストファイルを作成します。 24$testFile2 = $tempDir . DIRECTORY_SEPARATOR . 'report.log'; 25file_put_contents($testFile2, 'ログエントリ1' . PHP_EOL . 'ログエントリ2'); 26echo "テストファイルを作成しました: " . $testFile2 . "\n"; 27 28// ---------------------------------------------------------------------- 29// 2. GlobIterator を使用したファイルシステム走査と読み取り可能性のチェック 30// ---------------------------------------------------------------------- 31echo "\n--- GlobIterator::isReadable() の実行結果 ---\n"; 32 33try { 34 // 指定されたパターンに一致するファイルを見つけるためのGlobIteratorを作成します。 35 // ここでは、作成した一時ディレクトリ内のすべての .txt と .log ファイルを対象とします。 36 $pattern = $tempDir . DIRECTORY_SEPARATOR . '*.{txt,log}'; 37 38 // GlobIterator は SplFileInfo を継承しており、そのメソッドを呼び出すことができます。 39 // FilesystemIterator のフラグは、イテレータの挙動をより明示的に指定するためのものです。 40 $iterator = new GlobIterator($pattern, FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO); 41 42 // イテレータに一致するファイルがない場合のメッセージ 43 if (!$iterator->valid()) { 44 echo "注意: 指定されたパターン ('" . $pattern . "') に一致するファイルが見つかりませんでした。\n"; 45 } 46 47 // イテレータをループして、各要素の情報を取得し、読み取り可能性をチェックします。 48 foreach ($iterator as $fileInfo) { 49 // GlobIterator::isReadable() を呼び出して、現在の要素(ファイルまたはディレクトリ)が読み取り可能かを確認します。 50 // これは、SplFileInfo::isReadable() と同じ動作をします。 51 $isReadable = $iterator->isReadable(); 52 53 // 結果を画面に出力します。 54 echo "ファイル名: " . $fileInfo->getFilename() . "\n"; 55 echo " フルパス: " . $fileInfo->getPathname() . "\n"; 56 echo " 読み取り可能か?: " . ($isReadable ? 'はい' : 'いいえ') . "\n"; 57 echo "-----------------------------------\n"; 58 } 59 60} catch (UnexpectedValueException $e) { 61 // GlobIterator のコンストラクタに無効なパターンが渡された場合などに発生するエラーをキャッチします。 62 echo "エラーが発生しました: " . $e->getMessage() . "\n"; 63} finally { 64 // ---------------------------------------------------------------------- 65 // 3. 後処理: 作成した一時ファイルとディレクトリを削除してクリーンアップします。 66 // ---------------------------------------------------------------------- 67 echo "\n--- 後処理中 ---\n"; 68 if (file_exists($testFile1)) { 69 unlink($testFile1); 70 echo "削除しました: " . $testFile1 . "\n"; 71 } 72 if (file_exists($testFile2)) { 73 unlink($testFile2); 74 echo "削除しました: " . $testFile2 . "\n"; 75 } 76 // ディレクトリが空であることを確認してから削除します。 77 if (is_dir($tempDir)) { 78 // ディレクトリが空かどうかを確認 (FilesystemIterator を使用) 79 $dirIterator = new FilesystemIterator($tempDir); 80 if (!$dirIterator->valid()) { // ディレクトリが空の場合 81 rmdir($tempDir); 82 echo "削除しました: " . $tempDir . "\n"; 83 } else { 84 echo "注意: 一時ディレクトリ '" . $tempDir . "' が空でないため削除できませんでした。\n"; 85 } 86 } 87} 88 89?>
PHP 8のGlobIterator::isReadable()メソッドは、ファイルシステムを走査するGlobIteratorオブジェクトが現在指しているファイルやディレクトリが、現在のPHPスクリプトから読み取り可能であるかを判定します。このメソッドは引数を受け取らず、戻り値として真偽値(bool)を返します。ファイルやディレクトリが読み取り可能であればtrue、そうでなければfalseが返されます。
サンプルコードでは、一時的に作成されたテストファイルに対してGlobIteratorを使用し、各ファイルが読み取り可能かどうかを確認しています。foreachループ内で$iterator->isReadable()を呼び出すことで、現在の要素であるファイルに対する読み取り権限をチェックしています。例えば、スクリプトによって作成されたdocument1.txtやreport.logといったファイルに対しては、通常trueが返され、「はい」と表示されます。これは、それらのファイルが実際に存在し、PHPスクリプトがその内容を読み取れる状態であることを示しています。
このメソッドは、ファイルのコンテンツを読み込むなどの操作を行う前に、そのファイルが読み取り可能であるかを安全に確認するために利用できます。GlobIteratorはSplFileInfoを継承しているため、このisReadable()メソッドの動作はSplFileInfo::isReadable()と同様です。
GlobIterator::isReadable()は、イテレータが現在指すファイルやディレクトリが読み取り可能かを真偽値で返します。この機能は、スクリプトを実行するユーザーのファイルシステム権限に強く依存するため、実際の運用環境ではファイルのパーミッション設定に注意が必要です。GlobIteratorはSplFileInfoを継承しており、isReadable()はSplFileInfo::isReadable()と基本的に同じ動作をします。サンプルコードのように一時ファイルやディレクトリを扱う際は、必ずtry-catch-finallyブロックを用いてエラーを適切に処理し、作成したリソースをfinallyブロックで確実に削除する後処理を習慣づけることが、安全なシステム運用のために非常に重要です。
GlobIterator::isReadable()で読み取り不可を検出する
1<?php 2 3// このスクリプトが実行されるディレクトリに一時的なテスト用のディレクトリを作成します。 4$testDir = __DIR__ . '/temp_unreadable_test'; 5// テスト用ディレクトリ内に、読み取り不可にするファイルの名前を定義します。 6$testFile = $testDir . '/example_unreadable.txt'; 7 8// サンプルコード実行のためのメインロジック 9try { 10 // 1. テスト用のディレクトリを作成します。 11 // 既に存在する場合は何もしません。`true`はネストされたディレクトリも作成します。 12 if (!is_dir($testDir)) { 13 mkdir($testDir, 0777, true); 14 echo "テストディレクトリを作成しました: " . $testDir . PHP_EOL; 15 } else { 16 echo "テストディレクトリは既に存在します: " . $testDir . PHP_EOL; 17 } 18 19 // 2. 読み取り不可にするテストファイルを作成し、内容を書き込みます。 20 file_put_contents($testFile, "このファイルはテスト用です。\n"); 21 echo "テストファイルを作成しました: " . $testFile . PHP_EOL; 22 23 // 3. ファイルのパーミッションを000(読み取り、書き込み、実行不可)に設定します。 24 // この操作はUNIX系OSで最も効果的に機能します。Windowsでは異なる結果になる可能性があります。 25 // @を付けることで、chmodが失敗した場合に発生する警告を抑制し、戻り値で成否を判断します。 26 if (@chmod($testFile, 000)) { 27 echo "テストファイルのパーミッションを000(読み取り不可)に設定しました。" . PHP_EOL; 28 } else { 29 // chmodが失敗した場合は、後続のテストが意味をなさないため、エラーとして処理します。 30 // 作成したファイルは削除しておきます。 31 if (file_exists($testFile)) { 32 unlink($testFile); 33 } 34 throw new Exception("警告: テストファイルのパーミッションを000に設定できませんでした。この環境ではGlobIterator::isReadable()がfalseを返すケースをテストできない可能性があります。"); 35 } 36 37 echo PHP_EOL . "--- GlobIterator::isReadable() のテスト開始 ---" . PHP_EOL; 38 39 // GlobIterator を作成し、テストディレクトリ内のすべてのファイル/ディレクトリを対象とします。 40 // FilesystemIterator::KEY_AS_PATHNAME: イテレータのキーとしてパス名を使用します。 41 // FilesystemIterator::CURRENT_AS_FILEINFO: イテレータの値としてSplFileInfoオブジェクトを使用します。 42 // GlobIterator::GLOB_MARK: ディレクトリ名にスラッシュを追加します(オプション)。 43 $iterator = new GlobIterator($testDir . '/*', FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO | GlobIterator::GLOB_MARK); 44 45 // イテレータが有効な要素を指しているか(つまり、パターンにマッチする項目が見つかったか)確認します。 46 if ($iterator->valid()) { 47 // イテレータをループして、各要素の読み取り可能性をチェックします。 48 // foreach ($iterator as $name => $fileInfo) の $fileInfo は、 49 // GlobIterator::CURRENT_AS_FILEINFO オプションにより SplFileInfo オブジェクトですが、 50 // isReadable() メソッドはイテレータ自身(GlobIteratorオブジェクト)に対して呼び出すため、 51 // この $fileInfo 変数は直接使用していません。 52 foreach ($iterator as $name => $fileInfo) { 53 echo "対象パス: " . $name . PHP_EOL; 54 55 // GlobIterator::isReadable() メソッドを使用して、現在の要素が読み取り可能かチェックします。 56 // このメソッドは、イテレータが現在指しているSplFileInfoオブジェクトに対して 57 // isReadable()を呼び出すのと同等です。 58 if ($iterator->isReadable()) { 59 echo " isReadable(): true (この項目は読み取り可能です)" . PHP_EOL; 60 } else { 61 echo " isReadable(): false (この項目は読み取り不可能です)" . PHP_EOL; 62 } 63 } 64 } else { 65 echo "指定されたパターン '" . $testDir . '/*' . "' にマッチするファイル/ディレクトリが見つかりませんでした。" . PHP_EOL; 66 } 67 68 // 参考として、PHPの標準関数 is_readable() を使って確認します。 69 echo PHP_EOL . "--- PHP標準関数 is_readable() での確認 ---" . PHP_EOL; 70 if (file_exists($testFile)) { 71 // is_readable() はファイルが存在し、かつ読み取り可能であればtrueを返します。 72 echo "テストファイル '" . basename($testFile) . "' の is_readable() 結果: " . (is_readable($testFile) ? "true" : "false") . PHP_EOL; 73 } else { 74 echo "テストファイル '" . basename($testFile) . "' が存在しません。" . PHP_EOL; 75 } 76 77} catch (Exception $e) { 78 // 例外が発生した場合、エラーメッセージを出力します。 79 echo PHP_EOL . "エラーが発生しました: " . $e->getMessage() . PHP_EOL; 80} finally { 81 // 4. クリーンアップ: 作成したテストファイルとディレクトリを削除します。 82 echo PHP_EOL . "--- クリーンアップ処理 ---" . PHP_EOL; 83 if (file_exists($testFile)) { 84 // 削除できるように、一時的にパーミッションを元に戻します。 85 // @を付けてchmodの警告を抑制し、確実に削除を試みます。 86 @chmod($testFile, 0644); // 読み取り/書き込み可能にする 87 unlink($testFile); 88 echo "テストファイルを削除しました: " . $testFile . PHP_EOL; 89 } 90 if (is_dir($testDir)) { 91 // ディレクトリが空であることを確認してから削除します。 92 // rmdir() は空でないディレクトリは削除できません。 93 // scandirは'.'と'..'を含むので、空のディレクトリなら要素数は2になります。 94 $itemsInDir = array_diff(scandir($testDir), array('.', '..')); 95 if (empty($itemsInDir)) { 96 rmdir($testDir); 97 echo "テストディレクトリを削除しました: " . $testDir . PHP_EOL; 98 } else { 99 echo "警告: テストディレクトリ '" . $testDir . "' は空ではないため削除できませんでした。手動で削除してください。" . PHP_EOL; 100 } 101 } 102 echo "--- クリーンアップ完了 ---" . PHP_EOL; 103}
PHPのGlobIterator::isReadable()メソッドは、ファイルシステムをパターンマッチングで走査するGlobIteratorオブジェクトが、現在指しているファイルやディレクトリが読み取り可能かどうかを判定します。このメソッドは引数を取らず、読み取り可能であればtrueを、不可能であればfalseをbool値で返します。
サンプルコードでは、まず一時的なテストディレクトリを作成し、その中に特別なファイルを作成します。次に、chmod関数を使って、このファイルのパーミッションを000(読み取り、書き込み、実行がすべて禁止)に設定し、意図的に読み取り不可な状態を作り出しています。
その後、GlobIteratorを初期化してテストディレクトリ内のファイルを走査し、各要素に対して$iterator->isReadable()を呼び出しています。これにより、パーミッションを000に設定したファイルに対しては、isReadable()がfalseを返すことが確認できます。これは、システムがそのファイルへの読み取りアクセスを許可しないためです。読み取り可能な他の要素に対してはtrueが返されます。この機能は、アプリケーションが特定のファイルにアクセスする前に、そのファイルが読み取り可能であるかを確認する際に役立ちます。最後に、作成したテストファイルとディレクトリは適切にクリーンアップされます。
GlobIterator::isReadable()は、GlobIteratorが現在処理しているファイルやディレクトリが読み取り可能かをtrue/falseで判定します。このサンプルコードでは、ファイルを読み取り不可にするためにchmodを使用していますが、これはUNIX系OS特有の挙動であり、Windows環境では期待通りに動作しないことがありますので注意が必要です。また、chmodが失敗する可能性もあるため、エラー処理を確認してください。テスト後には、作成した一時ファイルやディレクトリのパーミッションを元に戻し、確実にクリーンアップする処理が非常に重要です。このメソッドは、PHPの標準関数is_readable()とは異なり、GlobIteratorの現在の要素に対して利用する点が特徴です。