首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 遍歷目錄必讀:is_file()/is_dir() 絕對路徑陷阱與正確姿勢

     編輯:PHP 綜合知識

經典翻車現場

$dir = $_SERVER['DOCUMENT_ROOT'] . '/inc/';
$d = opendir($dir);
while (false !== ($f = readdir($d))) {
    if (is_file($f)) {        // ❌ 錯誤:$f 只是文件名,相對當前工作目錄
        echo "<h2>$f</h2>";
    } else {
        echo "<h2>是目錄 $f</h2>";
    }
}
closedir($d);

輸出:只有 footer.html 被識別為文件,其餘全成「目錄」。

根因:相對路徑陷阱

  • readdir() 返回**不帶路徑的文件名**(如 header.html)
  • is_file() / is_dir() 默認相對**當前工作目錄**(getcwd()),而非 $dir
  • 若當前工作目錄下剛好有同名文件(如 footer.html),才會「巧合」判斷正確

正確姿勢:拼接絕對路徑

while (false !== ($f = readdir($d))) {
    $fullPath = $dir . $f;           // 或 "$dir/$f"
    if (is_file($fullPath)) {
        echo "<h2>$f</h2>";
    } else {
        echo "<h2>是目錄 $f</h2>";
    }
}

進階最佳實踐:SPL 迭代器一行搞定

$iterator = new FilesystemIterator($dir, FilesystemIterator::SKIP_DOTS);
foreach ($iterator as $fileInfo) {
    echo $fileInfo->isFile() ? "<h2>{$fileInfo->getFilename()}</h2>"
                             : "<h2>是目錄 {$fileInfo->getFilename()}</h2>";
}

優勢:
✅ 自動過濾 . ..
✅ 內建 isFile() isDir() getSize() getMTime() 等方法
✅ 物件導向,可鏈式調用 RegexIterator 過濾擴展名

避坑檢查清單

  • [ ] readdir/scandir/glob 返回值是否拼接了目錄路徑?
  • [ ] 是否處理了 . ..?
  • [ ] 是否考慮符號鏈接 is_link() 判斷?
  • [ ] 大目錄是否用 FilesystemIterator 避免一次性載入陣列?
  • [ ] Windows 下大小寫不敏感,strtolower() 統一比對?

總結

is_file($filename) 的 $filename **必須是相對執行腳本的完整路徑**,而非僅文件名。這是 PHP 文件系統函數「相對工作目錄」設計導致的最經典坑。養成 $full = $dir . $name 肌肉記憶,或直接升級 SPL 迭代器,一勞永逸。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved