PHP 提供 file_exists()、is_file()、is_dir() 三大函數檢查路徑存在性。本文說明各函數差異、快取陷阱、權限限制、符號連結行為與實戰封裝建議。
| 函數 | 檢查對象 | 回傳 true 條件 |
|---|---|---|
| file_exists | 檔案或目錄 | 路徑存在 (含符號連結指向存在目標) |
| is_file | 一般檔案 | 路徑存在且為一般檔案 (非目錄、非連結) |
| is_dir | 目錄 | 路徑存在且為目錄 |
<?php
$file = 'data.txt';
$dir = 'www.bkjia.com/newdata';
// 檢查檔案
if (file_exists($file)) {
echo "檔案 $file 存在\n";
} else {
echo "檔案 $file 不存在\n";
}
// 檢查目錄
if (is_dir($dir)) {
echo "目錄 $dir 存在\n";
} else {
echo "目錄 $dir 不存在\n";
}
// 組合判斷:確切是檔案
if (is_file($file)) {
echo "$file 是一般檔案\n";
}
?>
<?php
$file = 'test.txt';
touch($file);
var_dump(is_file($file)); // true
unlink($file);
var_dump(is_file($file)); // false (unlink 自動清除)
// 外部刪除情況
// 另一終端: rm test.txt
var_dump(is_file($file)); // 可能仍 true!
clearstatcache();
var_dump(is_file($file)); // 正確 false
?>
最佳實踐:封裝 safe_is_file()、safe_is_dir() 內建 clearstatcache(true, $path) (PHP 5.3+)。
is_link() 判斷是否為連結;is_file()/is_dir() 遵循連結檢查目標。false 並警告。//server/share/file 或 \\server\share\file。false。<?php
$info = new SplFileInfo('/path/to/file');
var_dump($info->isFile()); // 無快取,即時 stat
var_dump($info->isDir());
var_dump($info->isLink());
var_dump($info->getRealPath()); // 解析符號連結
?>
優點:物件導向、無快取問題、提供豐富中繼資料 (大小、時間、權限、擁有者)。
判斷存在性看似簡單,實則需區分「檔案/目錄/任一」、「快取/即時」、「連結/目標」。建立專案統一工具類 Filesystem::exists()、Filesystem::isFile()、Filesystem::isDir() 內建快取清除與 SplFileInfo 回退,能從根源消除此類 Bug。