項目中常需掃描目錄獲取所有文件路徑(如自動加載、批量處理、構建文件索引)。PHP 提供多種方式,本文對比兩種最常用的實現:glob() 遞歸與 DirectoryIterator (SPL) 迭代器。
<?php
function scanGlob($pattern) {
foreach (glob($pattern) as $path) {
if (is_dir($path)) {
scanGlob($path . '/*'); // 遞歸進入子目錄
} else {
echo $path . '<br/>'; // 處理文件
}
}
}
// 使用:掃描 D:/wamp/www/exe1 下所有文件
scanGlob('D:/wamp/www/exe1/*');
?>
特點:
. 和 ..,無需手動過濾。glob() 不區分大小寫;Linux 區分。<?php
function scanIterator($path) {
$dir = new DirectoryIterator($path);
foreach ($dir as $file) {
if ($file->isDot()) continue; // 跳過 . 和 ..
$full = $file->getPathname();
echo $full . '<br>';
if ($file->isDir()) {
scanIterator($full); // 遞歸
}
}
}
// 使用:掃描當前文件所在目錄的上兩級
scanIterator(dirname(dirname(__FILE__)));
?>
特點:
isDir(), isFile(), getSize(), getMTime(), getExtension() 等。isDot()。一行代碼實現遞歸遍歷,且可配合 RegexIterator 過濾:
<?php
$path = '/var/www/project';
$ri = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS));
// 僅獲取 .php 文件
$phpFiles = new RegexIterator($ri, '/\.php$/i');
foreach ($phpFiles as $file) {
echo $file->getPathname() . '<br>';
}
?>
| 維度 | glob() | DirectoryIterator | RecursiveIteratorIterator |
|---|---|---|---|
| 代碼簡潔度 | ★★★★★ | ★★★☆☆ | ★★★★★ |
| 內存效率 | 低 (全量數組) | 高 (逐個迭代) | 高 (逐個迭代) |
| 功能豐富度 | 低 (僅路徑) | 高 (SplFileInfo) | 高 (SplFileInfo) |
| 過濾靈活性 | 通配符 | 手動判斷 | 極高 (RegexIterator, CallbackFilterIterator) |
| 推薦場景 | 小目錄、一次性腳本、簡單通配符匹配 | 中大型目錄、需文件元信息、長運行進程 | 複雜過濾、多條件篩選、現代框架開發 |
glob(),開發效率最高。RecursiveDirectoryIterator 配合迭代器過濾器,內存安全、功能強大。glob() 路徑分隔符建議用正斜杠 /。try-catch。