基礎實現
function getfilecounts($ff) {
$dir = './'.$ff;
$handle = opendir($dir);
$i = 0;
while (false !== $file = readdir($handle)) {
if ($file !== '.' && $file != '..') {
$i++;
}
}
closedir($handle);
return $i;
}
現代化替代方案對比
| 方法 | 代碼 | 優點 | 缺點 |
scandir() | count(scandir($dir)) - 2 | 簡潔、內建 | 載入所有檔名到陣列,大目錄佔記憶體 |
glob() | count(glob($dir . '/*')) | 支援模式匹配 | 同樣載入所有結果 |
FilesystemIterator | iterator_count(new FilesystemIterator($dir, FilesystemIterator::SKIP_DOTS)) | 迭代器模式、記憶體效率高、可過濾 | PHP 5.3+ |
RecursiveIteratorIterator | 遞迴計數 | 支援子目錄 | 較複雜 |
推薦實現 (FilesystemIterator)
function countFiles(string $dir, bool $recursive = false): int {
if (!is_dir($dir)) {
throw new InvalidArgumentException("$dir is not a directory");
}
if ($recursive) {
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS)
);
} else {
$iterator = new FilesystemIterator($dir, FilesystemIterator::SKIP_DOTS);
}
return iterator_count($iterator);
}
進階功能擴展
按副檔名過濾
function countFilesByExtension(string $dir, array $extensions): int {
$iterator = new FilesystemIterator($dir, FilesystemIterator::SKIP_DOTS);
$count = 0;
foreach ($iterator as $file) {
if ($file->isFile() && in_array(strtolower($file->getExtension()), $extensions)) {
$count++;
}
}
return $count;
}
獲取檔案大小總和
function getDirectorySize(string $dir): int {
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS)
);
$size = 0;
foreach ($iterator as $file) {
if ($file->isFile()) $size += $file->getSize();
}
return $size;
}
效能建議
- 超大目錄 (10萬+ 檔案) 避免
scandir/glob,使用迭代器
- 頻繁查詢考慮快取 (Redis/檔案) 或資料庫記錄
- Linux 系統可用
exec('find ... | wc -l') 但需注意命令注入