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

PHP 目錄操作完全手冊:opendir/readdir、DirectoryIterator、Glob 與 SPL 迭代器的選擇指南

     編輯:PHP 相關知識

PHP 讀取目錄的四種主流方式

從傳統的 opendir() 到現代 SPL 迭代器,PHP 提供多層級的目錄操作 API。本文對比效能、記憶體、易用性,助你選擇最適合的方案。

1. 傳統資源型函數:opendir/readdir/closedir

<?php
$dir = 'filelist/';
$handle = opendir($dir);
if (!$handle) die("無法開啟目錄: $dir");

echo "目錄: $dir
"; while (($entry = readdir($handle)) !== false) { echo "$entry
"; } closedir($handle); ?>
  • 優點:記憶體效率高(逐行讀取)、PHP 4+ 相容。
  • 缺點:需手動管理資源、易忘記 closedir、需自行過濾 . ..。

2. 面向物件封裝:dir() 類

<?php
$d = dir("/etc/php5");
echo "Handle: {$d->handle}\nPath: {$d->path}\n";
while (false !== ($entry = $d->read())) {
    echo "$entry\n";
}
$d->close();
?>
  • 本質是 opendir 的薄封裝,提供 handle、path、read()、rewind()、close()。
  • 輸出包含 . ..,需自行過濾。

3. 現代 SPL 迭代器(推薦):DirectoryIterator / RecursiveDirectoryIterator

<?php
// 單層目錄
$iterator = new DirectoryIterator('filelist/');
foreach ($iterator as $fileinfo) {
    if ($fileinfo->isDot()) continue; // 自動過濾 . ..
    echo $fileinfo->getFilename() . "
"; // 可直接取得屬性 // $fileinfo->getSize(), ->getMTime(), ->isDir(), ->isFile(), ->getPerms()... } // 遞迴遍歷(含子目錄) $recursive = new RecursiveIteratorIterator( new RecursiveDirectoryIterator('filelist/', RecursiveDirectoryIterator::SKIP_DOTS) ); foreach ($recursive as $fileinfo) { echo $fileinfo->getPathname() . " (" . ($fileinfo->isDir() ? 'DIR' : 'FILE') . ")
"; } ?>
  • 優點:物件導向、豐富屬性方法(SplFileInfo)、自動過濾 . ..、支援遞迴、可搭配 RegexIterator 過濾。
  • 記憶體:延遲載入,僅迭代當前項目,適合大量檔案。

4. 模式匹配:glob()

<?php
// 取得所有 .php 檔案
$files = glob('filelist/*.php');
foreach ($files as $file) {
    echo basename($file) . "
"; } // 遞迴模式(PHP 5.5+ 需 GLOB_BRACE) $files = glob('filelist/**/*.php', GLOB_BRACE); ?>
  • 回傳完整路徑陣列,一次性載入記憶體,不適合超大目錄。
  • 支援通配符 *、?、[...]、{...}。

輔助函數:路徑資訊與磁碟空間

目錄建立與刪除

<?php
// 建立(權限 0777 受 umask 影響,Windows 忽略權限)
mkdir('path/to/dir', 0777, true); // true = 遞迴建立

// 刪除(目錄必須為空)
rmdir('path/to/dir');

// 遞迴刪除非空目錄
function rrmdir($dir) {
    $it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
    $it = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
    foreach ($it as $file) {
        $file->isDir() ? rmdir($file->getPathname()) : unlink($file->getPathname());
    }
    rmdir($dir);
}
?>

選擇建議

函數用途範例
dirname($path)取得目錄部分dirname('/a/b/c.txt') // '/a/b'
basename($path)取得檔名部分basename('/a/b/c.txt') // 'c.txt'
disk_free_space($path)剩餘空間(位元組)disk_free_space('/')
disk_total_space($path)總空間disk_total_space('/')
場景推薦方式理由
簡單列出單層檔案DirectoryIteratorOOP 風格、自動過濾 . ..、豐富屬性
遞迴遍歷大量檔案RecursiveDirectoryIterator + RecursiveIteratorIterator記憶體效率高、可中斷、可過濾
模式匹配(如 *.log)glob()語法簡潔、回傳陣列易處理
舊專案維護/極簡環境opendir/readdir無依賴、相容性最好

總結

現代 PHP 專案首選 SPL 迭代器,兼具效能、記憶體效率與豐富功能。glob() 適合簡單模式匹配,opendir 僅作為底層理解或相容舊代碼。記得善用 SplFileInfo 直接取得檔案屬性,避免重複 stat 系統呼叫。

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