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

PHP 遞歸列出目錄內容:檔案連結生成、過濾系統檔案

     編輯:PHP 綜合知識

基礎非遞歸版

function list_files(string $dir): void {
    if (!is_dir($dir)) return;
    $dh = opendir($dir);
    while (($file = readdir($dh)) !== false) {
        if ($file === '.' || $file === '..' || $file === 'Thumbs.db') continue;
        $path = $dir . $file;
        echo '<a href="' . htmlspecialchars($path) . '" target="_blank">' . htmlspecialchars($file) . '</a><br>';
    }
    closedir($dh);
}

遞歸版(含子目錄)

function list_files_recursive(string $dir, int $depth = 0): void {
    if (!is_dir($dir)) return;
    $dh = opendir($dir);
    while (($file = readdir($dh)) !== false) {
        if ($file === '.' || $file === '..' || $file === 'Thumbs.db') continue;
        $path = $dir . DIRECTORY_SEPARATOR . $file;
        $indent = str_repeat(' ', $depth * 4);
        if (is_dir($path)) {
            echo $indent . '<strong>📁 ' . htmlspecialchars($file) . '</strong><br>';
            list_files_recursive($path, $depth + 1);
        } else {
            echo $indent . '<a href="' . htmlspecialchars($path) . '" target="_blank">' . htmlspecialchars($file) . '</a><br>';
        }
    }
    closedir($dh);
}

現代最佳實踐:RecursiveDirectoryIterator

function list_files_modern(string $dir): Generator {
    $iterator = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS),
        RecursiveIteratorIterator::SELF_FIRST
    );
    
    foreach ($iterator as $file) {
        if ($file->getFilename() === 'Thumbs.db') continue;
        yield [
            'path'   => $file->getPathname(),
            'name'   => $file->getFilename(),
            'isDir'  => $file->isDir(),
            'size'   => $file->getSize(),
            'mtime'  => $file->getMTime(),
            'depth'  => $iterator->getDepth(),
        ];
    }
}

// 使用
foreach (list_files_modern('/var/www') as $info) {
    $indent = str_repeat('  ', $info['depth']);
    $icon = $info['isDir'] ? '📁' : '📄';
    echo "$indent$icon {$info['name']} (" . format_bytes($info['size']) . ")<br>";
}

function format_bytes(int $bytes): string {
    $units = ['B','KB','MB','GB','TB'];
    $i = 0;
    while ($bytes >= 1024 && $i < 4) { $bytes /= 1024; $i++; }
    return round($bytes, 2) . ' ' . $units[$i];
}

效能與記憶體對比

方法記憶體速度功能
scandir() + 遞歸中(全載入陣列)快簡單
opendir/readdir低(流式)快可控
RecursiveDirectoryIterator極低 (Generator)快豐富資訊、可過濾、可排序
glob()高(全路徑陣列)慢模式匹配

安全提醒

  • 禁止直接暴露服務器絕對路徑給前端;提供下載請用 PHP 代理輸出。
  • 過濾 .. 防止目錄遍歷攻擊。
  • 大目錄建議分頁或 AJAX 懶加載,避免單次響應過大。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved