【PHP8.x】realpath()関数の使い方
realpath関数の使い方について、初心者にもわかりやすく解説します。
基本的な使い方
『realpath関数は、指定されたパス文字列に含まれる全てのシンボリックリンク、/./ や /../ といった相対パスの参照、そして余分なパス区切り文字を解決し、正規化された絶対パスを返す処理を実行する関数です。この関数は、引数に与えられたパスが実際にファイルシステム上に存在するかどうかを確認し、存在する場合にのみパス文字列を返します。相対パス、絶対パスのどちらも引数として指定可能です。例えば、シンボリックリンクをたどって元のファイルの絶対パスを取得したい場合や、../../ のような記述を含む複雑なパスを、ルートディレクトリから始まる一意の単純なパスに変換したい場合などに使用されます。処理が成功すると、末尾にスラッシュを含まない正規化された絶対パスが文字列として返されます。一方、指定されたパスが存在しない、またはパスの途中のディレクトリにアクセス権限がないなどの理由で解決できない場合には false を返します。これにより、ファイルの存在確認と正規化されたパスの取得を同時に行うことができます。
構文(syntax)
1<?php 2 3$absolute_path = realpath('/path/to/your/file.txt'); 4 5?>
引数(parameters)
string $path
- string $path: 正規化された絶対パスに変換したいファイルまたはディレクトリへのパスを指定する文字列
戻り値(return)
string|false
指定されたパスの正規化された絶対パスを文字列で返します。指定されたパスが存在しない場合はfalseを返します。
サンプルコード
PHP realpath キャッシュサイズを設定・取得する
1<?php 2 3// realpath_cache_size の設定例 4 5// realpath キャッシュのサイズを 4MB に設定する 6ini_set('realpath_cache_size', '4M'); 7 8// 現在の realpath キャッシュサイズを取得する 9$cache_size = ini_get('realpath_cache_size'); 10 11echo "現在の realpath キャッシュサイズ: " . $cache_size . "\n"; 12 13// realpath() を使用して絶対パスを取得する 14$relative_path = 'test.txt'; 15$absolute_path = realpath($relative_path); 16 17if ($absolute_path === false) { 18 echo "ファイルが見つかりませんでした。\n"; 19} else { 20 echo "相対パス: " . $relative_path . "\n"; 21 echo "絶対パス: " . $absolute_path . "\n"; 22} 23 24?>
このサンプルコードは、PHPのrealpath()関数とrealpath_cache_sizeの設定について解説しています。realpath()関数は、引数に指定された相対パスを絶対パスに変換します。もしファイルが存在しない場合はfalseを返します。
realpath_cache_sizeは、realpath()関数が変換したパスをキャッシュするサイズを設定するための設定です。キャッシュを利用することで、同じパスに対するrealpath()の呼び出しを高速化できます。サンプルコードでは、ini_set()関数を使ってrealpath_cache_sizeを4MBに設定しています。設定値はini_get()関数で確認できます。
コード例ではまず、realpath_cache_sizeを4MBに設定し、現在のキャッシュサイズを表示します。次に、test.txtという相対パスをrealpath()関数で絶対パスに変換しています。もしtest.txtが存在しなければ、「ファイルが見つかりませんでした。」と表示されます。存在する場合は、相対パスと絶対パスをそれぞれ表示します。
realpath()関数は、ファイルやディレクトリの存在確認や、パスの正規化に役立ちます。realpath_cache_sizeを適切に設定することで、パフォーマンスを向上させることができます。
realpath()関数は、指定された相対パスを絶対パスに変換する関数です。realpath_cache_sizeは、realpath()の結果をキャッシュするメモリサイズを設定します。キャッシュサイズを大きくすると、realpath()の処理が高速化される可能性がありますが、メモリ消費量が増加します。ini_set()で設定を変更した場合、スクリプトの実行中のみ有効です。php.iniで設定すると永続的に変更できます。realpath()は、ファイルが存在しない場合falseを返すため、必ず戻り値を確認しましょう。ファイルパスはOSによって扱いが異なるため、異なる環境で動作させる場合は注意が必要です。
PHPで存在しないファイルのrealpathを取得する
1<?php 2 3/** 4 * 指定されたパスの絶対パスを返します。 5 * ファイルやディレクトリが存在しない場合でも、存在しないパスの絶対パスを返そうとします。 6 * 7 * @param string $path 相対パスまたは絶対パス 8 * @return string|false 絶対パス。エラー時は false 9 */ 10function get_absolute_path(string $path): string|false 11{ 12 // 一時ファイルを作成して、realpath() を利用する 13 $temp_file = tempnam(sys_get_temp_dir(), 'temp_'); 14 if ($temp_file === false) { 15 return false; 16 } 17 unlink($temp_file); // 一時ファイルを削除 18 19 // 指定されたパスと一時ファイルを結合 20 $combined_path = $path . '/' . basename($temp_file); 21 22 // realpath() を使用して絶対パスを取得 23 $absolute_path = realpath($combined_path); 24 25 if ($absolute_path === false) { 26 return false; 27 } 28 29 // 最後に生成したファイル名を削除 30 $absolute_path = str_replace('/' . basename($temp_file), '', $absolute_path); 31 return $absolute_path; 32} 33 34// 使用例 35$relative_path = 'path/to/non/existing/file'; 36$absolute_path = get_absolute_path($relative_path); 37 38if ($absolute_path !== false) { 39 echo "Absolute path: " . $absolute_path . PHP_EOL; 40} else { 41 echo "Failed to get absolute path." . PHP_EOL; 42} 43
このサンプルコードは、PHPのrealpath()関数を用いて、存在しないファイルやディレクトリを含むパスの絶対パスを取得する方法を示しています。通常のrealpath()関数は、ファイルやディレクトリが存在しない場合にfalseを返しますが、この例では、一時ファイルを作成し、それをパスに結合することで、存在しないパスでも絶対パスを解決しようと試みます。
まず、get_absolute_path()関数は、引数として相対パスまたは絶対パス $path を受け取ります。関数内部では、tempnam()関数を使って一時ファイルを作成し、そのファイル名をパスに結合します。次に、realpath()関数を用いて結合されたパスの絶対パスを取得します。最後に、一時ファイル名をパスから取り除くことで、元のパスに対応する絶対パスを返します。
realpath()関数が失敗した場合や、一時ファイルの作成に失敗した場合は、関数はfalseを返します。
使用例では、path/to/non/existing/fileという存在しない相対パスをget_absolute_path()関数に渡し、絶対パスを取得しています。取得した絶対パスは、成功すれば表示され、失敗すればエラーメッセージが表示されます。この手法は、例えば、設定ファイルが存在しない場合に、その設定ファイルを配置すべき絶対パスを動的に決定するような場合に役立ちます。
realpath()関数は、通常、ファイルやディレクトリが存在しない場合はfalseを返します。このサンプルコードは、存在しないパスの絶対パスを取得するために、一時ファイルを作成し、そのファイル名と指定されたパスを組み合わせてrealpath()を使用する工夫をしています。
注意点として、一時ファイルの作成にはtempnam()関数を使用していますが、作成場所はシステムのテンポラリディレクトリ(sys_get_temp_dir())です。このディレクトリへの書き込み権限がない場合、エラーが発生する可能性があります。また、unlink()で一時ファイルを削除していますが、タイミングによっては削除に失敗する可能性も考慮する必要があります。
セキュリティ面では、basename()関数の使用に注意してください。予期せぬファイル名が$pathに含まれている場合、意図しない絶対パスが生成される可能性があります。入力を適切に検証することで、セキュリティリスクを軽減できます。
PHP realpath() 動作と「not working」を解説する
1<?php 2 3/** 4 * realpath() 関数の動作と「realpath not working」のケースを実演します。 5 * 6 * realpath() は、指定されたパスの絶対パスを解決して返します。 7 * しかし、パスが存在しない、アクセスできない、または解決できない場合、false を返します。 8 * この「false」が返される状況が「not working」と表現されることがあります。 9 */ 10function demonstrateRealpathNotWorking(): void 11{ 12 // --- テスト用のファイルとディレクトリを準備 --- 13 $testFile = 'temp_test_file.txt'; 14 $testDir = 'temp_test_dir'; 15 16 // 存在するファイルを作成 17 file_put_contents($testFile, 'This is a test content.'); 18 // 存在するディレクトリを作成 19 if (!is_dir($testDir)) { 20 mkdir($testDir); 21 } 22 23 echo "--- realpath() の動作確認 --- \n\n"; 24 25 // ケース1: 存在するファイルへの realpath 26 echo "【ケース1】存在するファイルへの realpath:\n"; 27 $path1 = $testFile; 28 $resolvedPath1 = realpath($path1); 29 if ($resolvedPath1 !== false) { 30 echo " 成功: 元のパス '{$path1}' -> 解決されたパス '{$resolvedPath1}'\n"; 31 } else { 32 echo " 失敗: 元のパス '{$path1}' の解決に失敗しました。\n"; 33 echo " 原因: ファイルが存在しないか、アクセス権限がない可能性があります。\n"; 34 } 35 echo "\n"; 36 37 // ケース2: 存在するディレクトリへの realpath 38 echo "【ケース2】存在するディレクトリへの realpath:\n"; 39 $path2 = $testDir; 40 $resolvedPath2 = realpath($path2); 41 if ($resolvedPath2 !== false) { 42 echo " 成功: 元のパス '{$path2}' -> 解決されたパス '{$resolvedPath2}'\n"; 43 } else { 44 echo " 失敗: 元のパス '{$path2}' の解決に失敗しました。\n"; 45 echo " 原因: ディレクトリが存在しないか、アクセス権限がない可能性があります。\n"; 46 } 47 echo "\n"; 48 49 // ケース3: 存在しないファイルへの realpath (これが「not working」の一例です) 50 echo "【ケース3】存在しないファイルへの realpath (realpath not working の典型例):\n"; 51 $path3 = 'non_existent_file.txt'; 52 $resolvedPath3 = realpath($path3); 53 if ($resolvedPath3 !== false) { 54 echo " 成功: 元のパス '{$path3}' -> 解決されたパス '{$resolvedPath3}'\n"; 55 } else { 56 echo " 失敗: 元のパス '{$path3}' の解決に失敗しました。\n"; 57 echo " 原因: ファイルが存在しません。realpath() は存在しないパスは解決できません。\n"; 58 echo " 対処法: realpath() を呼び出す前に file_exists() などでファイルの存在を確認することを検討してください。\n"; 59 } 60 echo "\n"; 61 62 // ケース4: 存在しないディレクトリへの realpath (これも「not working」の一例です) 63 echo "【ケース4】存在しないディレクトリへの realpath (realpath not working の典型例):\n"; 64 $path4 = 'non_existent_dir'; 65 $resolvedPath4 = realpath($path4); 66 if ($resolvedPath4 !== false) { 67 echo " 成功: 元のパス '{$path4}' -> 解決されたパス '{$resolvedPath4}'\n"; 68 } else { 69 echo " 失敗: 元のパス '{$path4}' の解決に失敗しました。\n"; 70 echo " 原因: ディレクトリが存在しません。realpath() は存在しないパスは解決できません。\n"; 71 echo " 対処法: realpath() を呼び出す前に is_dir() などでディレクトリの存在を確認することを検討してください。\n"; 72 } 73 echo "\n"; 74 75 // ケース5: 相対パスや特殊なパス (例: "./") の解決 76 echo "【ケース5】相対パスへの realpath:\n"; 77 $path5 = './' . $testFile; // カレントディレクトリ内のファイル 78 $resolvedPath5 = realpath($path5); 79 if ($resolvedPath5 !== false) { 80 echo " 成功: 元のパス '{$path5}' -> 解決されたパス '{$resolvedPath5}'\n"; 81 } else { 82 echo " 失敗: 元のパス '{$path5}' の解決に失敗しました。\n"; 83 echo " 原因: パスが存在しないか、アクセス権限がない可能性があります。\n"; 84 } 85 echo "\n"; 86 87 // --- 後処理 --- 88 // 作成したファイルとディレクトリを削除し、環境をクリーンアップします。 89 if (file_exists($testFile)) { 90 unlink($testFile); 91 echo "テストファイル '{$testFile}' を削除しました。\n"; 92 } 93 if (is_dir($testDir)) { 94 rmdir($testDir); 95 echo "テストディレクトリ '{$testDir}' を削除しました。\n"; 96 } 97} 98 99// 関数を実行して realpath() の動作を確認します。 100demonstrateRealpathNotWorking(); 101 102?>
realpath関数は、PHPで指定されたパスの「実体のある絶対パス」を解決するために使用されます。引数として解決したいパス(string $path)を受け取ります。この関数が成功した場合、解決された絶対パスを文字列として返しますが、指定されたパスが存在しない、アクセスできない、シンボリックリンクが不正であるなどの理由で解決できない場合は、falseを返します。
キーワード「realpath not working」は、このrealpath関数が期待通りの絶対パスを返さず、代わりにfalseを返す状況を指すことが多いです。サンプルコードでは、この挙動を具体的に示しています。存在するファイルやディレクトリに対してrealpathを実行すると、正しく絶対パスが返されることが確認できます。一方で、存在しないファイルやディレクトリに対してこの関数を呼び出すと、falseが戻り値として得られます。これはrealpathがパスの存在を前提としているためで、多くの場合、「realpath not working」と表現されるのは、このような存在しないパスを指定したケースです。realpathを使用する際は、戻り値がfalseでないかを必ず確認し、必要に応じてfile_exists()やis_dir()などで事前にパスの存在を確認することをお勧めします。
realpath関数は、指定されたパスが存在しない、またはアクセス権がない場合、エラーではなくfalseを返します。これが「realpath not working」と表現される状況です。関数の戻り値は必ず!== falseで厳密に確認し、結果に応じて処理を分岐させることが重要です。存在しないパスに対してはfalseを返すため、事前にfile_exists()やis_dir()などでパスの存在を確認すると、意図しない失敗を防ぎ、より安全なコードになります。また、相対パスを与えた場合でも、実際に存在するパスを絶対パスに変換して返す点が特徴です。
PHP: realpath() とシンボリックリンクを解決する
1<?php 2 3/** 4 * realpath() 関数とシンボリックリンクの動作をデモンストレーションする。 5 * 6 * この関数は、一時ファイルとそれへのシンボリックリンクを作成し、 7 * realpath() を使用してシンボリックリンクが指す実際のファイルの絶対パスを解決する過程を示す。 8 * 最後に作成したファイルとシンボリックリンクをクリーンアップする。 9 */ 10function demonstrateRealpathSymlinkExample(): void 11{ 12 // 一時ファイル名とそれに対するシンボリックリンク名を設定 13 $originalFileName = 'original_file_for_realpath_example.txt'; 14 $symlinkName = 'symlink_for_realpath_example.txt'; 15 16 // 現在のスクリプトがあるディレクトリに、ファイルとシンボリックリンクの絶対パスを構築 17 $originalFilePath = __DIR__ . DIRECTORY_SEPARATOR . $originalFileName; 18 $symlinkPath = __DIR__ . DIRECTORY_SEPARATOR . $symlinkName; 19 20 // スクリプトの実行終了時に必ずファイルとシンボリックリンクを削除するための無名関数 21 // これにより、スクリプトが途中でエラー終了しても一時ファイルが残りません。 22 $cleanup = function() use ($originalFilePath, $symlinkPath): void { 23 echo "\n--- クリーンアップ中 ---" . PHP_EOL; 24 // シンボリックリンクの削除 25 if (is_link($symlinkPath)) { // パスがシンボリックリンクであることを確認 26 if (unlink($symlinkPath)) { 27 echo "シンボリックリンクを削除しました: {$symlinkPath}" . PHP_EOL; 28 } else { 29 echo "エラー: シンボリックリンクの削除に失敗しました: {$symlinkPath}" . PHP_EOL; 30 } 31 } elseif (file_exists($symlinkPath)) { 32 // 万が一、シンボリックリンク作成が失敗して通常のファイルができてしまった場合の削除 33 if (unlink($symlinkPath)) { 34 echo "誤って作成されたファイルを削除しました: {$symlinkPath}" . PHP_EOL; 35 } else { 36 echo "エラー: 誤って作成されたファイルの削除に失敗しました: {$symlinkPath}" . PHP_EOL; 37 } 38 } 39 40 // 元のファイルの削除 41 if (file_exists($originalFilePath)) { // 元のファイルが存在することを確認 42 if (unlink($originalFilePath)) { 43 echo "元のファイルを削除しました: {$originalFilePath}" . PHP_EOL; 44 } else { 45 echo "エラー: 元のファイルの削除に失敗しました: {$originalFilePath}" . PHP_EOL; 46 } 47 } 48 echo "クリーンアップ完了。" . PHP_EOL; 49 }; 50 51 // スクリプトが終了する際に上記クリーンアップ関数を実行するよう登録 52 register_shutdown_function($cleanup); 53 54 echo "--- realpath() とシンボリックリンクのデモンストレーション ---" . PHP_EOL; 55 56 // 1. 元のファイルを作成 57 echo "1. 元のファイルを作成: {$originalFilePath}" . PHP_EOL; 58 if (file_put_contents($originalFilePath, "これは元のファイルの内容です。\n") === false) { 59 echo "エラー: 元のファイルの作成に失敗しました。スクリプトを終了します。" . PHP_EOL; 60 return; // エラー時は処理を終了し、クリーンアップはregister_shutdown_functionで実行される 61 } 62 echo " 元のファイルが存在することを確認: " . (file_exists($originalFilePath) ? "はい" : "いいえ") . PHP_EOL; 63 64 // 2. 元のファイルへのシンボリックリンクを作成 65 // 注意: Windows環境では、この操作に管理者権限が必要な場合があります。 66 // Unix系OS (Linux, macOS, WSLなど) での実行を推奨します。 67 echo "\n2. 元のファイルへのシンボリックリンクを作成:" . PHP_EOL; 68 echo " リンク元 (ターゲットファイル): {$originalFilePath}" . PHP_EOL; 69 echo " リンク先 (シンボリックリンク名): {$symlinkPath}" . PHP_EOL; 70 71 if (!symlink($originalFilePath, $symlinkPath)) { // 絶対パスを使用してシンボリックリンクを作成 72 echo "警告: シンボリックリンクの作成に失敗しました。" . PHP_EOL; 73 echo " (Windows環境では管理者権限が必要な場合があります。Unix系OSでの実行を推奨します。)" . PHP_EOL; 74 return; // シンボリックリンクが作成できない場合、これ以上のテストは無意味なため終了 75 } 76 echo " シンボリックリンクが存在することを確認: " . (file_exists($symlinkPath) ? "はい" : "いいえ") . PHP_EOL; 77 echo " シンボリックリンクであることを確認 (is_link()): " . (is_link($symlinkPath) ? "はい" : "いいえ") . PHP_EOL; 78 79 80 // 3. シンボリックリンクのパスを realpath() に渡し、実際のパスを解決 81 echo "\n3. realpath() を使用してシンボリックリンクを解決:" . PHP_EOL; 82 echo " 入力パス (シンボリックリンク): {$symlinkPath}" . PHP_EOL; 83 $resolvedPath = realpath($symlinkPath); 84 85 if ($resolvedPath !== false) { 86 // realpath() は、シンボリックリンクを解決し、実際のファイルの絶対パスを返します。 87 echo " 解決された絶対パス (realpath): {$resolvedPath}" . PHP_EOL; 88 echo " 元のファイルの絶対パス: {$originalFilePath}" . PHP_EOL; 89 if ($resolvedPath === $originalFilePath) { 90 echo " 結果: realpath() はシンボリックリンクを正しく解決しました。" . PHP_EOL; 91 } else { 92 echo " 結果: realpath() の解決パスが元のファイルパスと異なります (予期せぬ結果)。" . PHP_EOL; 93 } 94 } else { 95 echo " エラー: realpath() がパスを解決できませんでした。パスが存在しないか、アクセス権がありません。" . PHP_EOL; 96 } 97 98 // 4. 存在しないパスを realpath() に渡した場合の挙動 99 echo "\n4. 存在しないパスを realpath() に渡す場合:" . PHP_EOL; 100 $nonExistentPath = __DIR__ . DIRECTORY_SEPARATOR . 'non_existent_file_example.txt'; 101 echo " 入力パス: {$nonExistentPath}" . PHP_EOL; 102 $resultNonExistent = realpath($nonExistentPath); 103 if ($resultNonExistent === false) { 104 echo " 結果: realpath() は false を返しました (期待通り)。" . PHP_EOL; 105 } else { 106 echo " 結果: realpath() は {$resultNonExistent} を返しました (期待と異なる)。" . PHP_EOL; 107 } 108 109 echo "\nデモンストレーション完了。" . PHP_EOL; 110} 111 112// デモンストレーション関数を実行 113demonstrateRealpathSymlinkExample(); 114 115?>
PHP 8のrealpath()関数は、指定されたパスを正規化し、シンボリックリンク(別のファイルやディレクトリへの参照)を解決して、最終的なファイルの絶対パスを返します。引数には解決したいパスを文字列で指定し、成功した場合はその絶対パスを文字列で返しますが、パスが存在しない、またはアクセスできない場合はfalseを返します。
このサンプルコードでは、realpath()関数がシンボリックリンクをどのように処理するかを実演しています。まず、プログラムが実行されているディレクトリに一時的な元のファイルを作成し、次にそのファイルへのシンボリックリンクを作成します。その後、作成したシンボリックリンクのパスをrealpath()に渡すと、関数はシンボリックリンクが指し示している実際の元のファイルの絶対パスを正確に取得できることを確認できます。これにより、realpath()がシンボリックリンクの実体を見つけ出す機能が示されます。また、存在しないパスを渡した場合には、realpath()がエラーを示すfalseを返す挙動も確認できます。サンプルコードは実行後に作成したファイルとシンボリックリンクを自動的に削除し、クリーンな状態を保ちます。なお、Windows環境でシンボリックリンクを作成するには管理者権限が必要な場合があります。
realpath関数は、シンボリックリンクを解決し、実ファイルの正規化された絶対パスを返します。ファイルが存在しない場合やアクセス権がない場合、またはエラーが発生した場合はfalseを返すため、必ず戻り値をfalseと比較してエラー処理を行ってください。
サンプルコードでシンボリックリンクを作成するsymlink関数は、Windows環境では管理者権限が必要な場合があります。Unix系OS(Linux、macOS、WSLなど)での実行がスムーズです。パスは__DIR__定数とDIRECTORY_SEPARATORを使って構築すると、OSの違いを吸収し、移植性が高く安定した動作が期待できます。