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

PHP 遞歸遍歷目錄完整實現:從基礎到實戰

     編輯:PHP 相關知識

文件系統操作是 PHP 後端開發常見需求。本文通過一個完整的「目錄瀏覽器」示例,講解遞歸遍歷目錄的核心函數、邏輯結構與安全注意點。

核心函數速覽

函數用途
opendir()打開目錄句柄
readdir()讀取目錄條目
is_dir()判斷是否為目錄
chdir()切換工作目錄
getcwd()獲取當前工作目錄
base64_encode()路徑編碼傳遞(URL 安全)

完整實現代碼(單文件版)

<?php
// 6.php - 目錄瀏覽入口
if (isset($_GET['id'])) {
    $path = base64_decode(str_replace(' ', '+', $_GET['id']));
    if (is_dir($path)) {
        chdir($path);
    }
}

$handle = opendir('.');
echo "<h3>當前目錄: " . htmlspecialchars(getcwd()) . "</h3>";
echo "<ul>";

while (false !== ($entry = readdir($handle))) {
    if ($entry === '.' ) continue; // 跳過當前目錄
    
    $fullPath = getcwd() . DIRECTORY_SEPARATOR . $entry;
    $encodedPath = base64_encode($fullPath);
    
    if (is_dir($fullPath)) {
        if ($entry === '..') {
            echo "<li><a href='6.php?id={$encodedPath}'>📁 上一級</a></li>";
        } else {
            echo "<li><a href='6.php?id={$encodedPath}'>📁 {$entry}</a></li>";
        }
    } else {
        echo "<li>📄 {$entry} <small>(" . filesize($fullPath) . " bytes)</small></li>";
    }
}
echo "</ul>";
closedir($handle);
?>

遞歸函數封裝版(推薦用於項目)

function scanDirRecursive($dir, $depth = 0) {
    $result = [];
    if (!is_dir($dir)) return $result;
    
    $items = scandir($dir);
    foreach ($items as $item) {
        if ($item === '.' || $item === '..') continue;
        
        $path = $dir . DIRECTORY_SEPARATOR . $item;
        $info = [
            'name' => $item,
            'path' => $path,
            'type' => is_dir($path) ? 'dir' : 'file',
            'size' => is_file($path) ? filesize($path) : 0,
            'mtime' => filemtime($path),
            'depth' => $depth
        ];
        
        if (is_dir($path)) {
            $info['children'] = scanDirRecursive($path, $depth + 1);
        }
        $result[] = $info;
    }
    return $result;
}

// 使用示例
$tree = scanDirRecursive('/var/www/html');
echo json_encode($tree, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);

安全與性能優化要點

  • 路徑穿透防護: 必須驗證解碼後路徑在允許根目錄內 strpos($realPath, $allowedRoot) === 0
  • 權限控制: 結合用戶角色過濾可見目錄
  • 大目錄優化: 使用 scandir() 替代 readdir() 循環,或引入 RecursiveDirectoryIterator (SPL)
  • 內存管理: 遞歸深度過大時改用迭代器模式,防止棧溢出
  • 緩存策略: 目錄結構變動較少時,緩存掃描結果

現代化替代方案

// PHP 5.3+ SPL 迭代器(更優雅、可控)
$iterator = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator('/path', FilesystemIterator::SKIP_DOTS),
    RecursiveIteratorIterator::SELF_FIRST
);

foreach ($iterator as $fileInfo) {
    echo str_repeat('  ', $iterator->getDepth()) . $fileInfo->getFilename() . "\n";
}

選擇合適方案:簡單展示用遞歸函數,生產環境推薦 SPL 迭代器配合權限檢查。

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