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

PHP 目錄遍歷函數 opendir/readdir 完整用法指南

     編輯:PHP 相關知識

PHP 目錄遍歷函數 opendir/readdir 完整用法指南

opendir()、readdir()、closedir() 是 PHP 檔案系統操作的基礎組合,用於開啟目錄句柄、逐項讀取、關閉釋放資源。本文詳細說明語法、參數、常見模式與進階替代方案 (SPL)。

基本語法與流程

<?php
$dir = "./"; // 目標目錄

// 1. 開啟目錄句柄
if (is_dir($dir)) {
    if ($dh = opendir($dir)) {
        // 2. 迴圈讀取每一項
        while (($file = readdir($dh)) !== false) {
            // $file 僅為檔名,需拼接完整路徑才能用 filetype(), filesize() 等
            $fullPath = $dir . $file;
            echo "檔名: $file | 類型: " . filetype($fullPath) . "
"; } // 3. 關閉句柄 (重要!釋放系統資源) closedir($dh); } else { echo "無法開啟目錄: $dir"; } } else { echo "路徑不是目錄: $dir"; } ?>

關鍵函數說明

函數說明回傳值
opendir(path, context)開啟目錄句柄。context 可選,用於流上下文 (如 FTP、HTTP 協議)。資源 handle 或 false
readdir(handle)讀取目錄下一項 (含 . ..)。檔名字串或 false (結束)
closedir(handle)關閉目錄句柄。bool
rewinddir(handle)將指標重置到目錄開頭。void
scandir(path)一次性讀取整個目錄到陣列 (內建排序),簡單場合更方便。陣列

常見模式:遞迴遍歷子目錄

<?php
function listDirRecursive($path, $indent = '') {
    $dh = @opendir($path);
    if (!$dh) return;
    
    while (($file = readdir($dh)) !== false) {
        if ($file === '.' || $file === '..') continue;
        $full = $path . DIRECTORY_SEPARATOR . $file;
        
        if (is_dir($full)) {
            echo $indent . "📁 $file
"; listDirRecursive($full, $indent . '    '); } else { echo $indent . "📄 $file
"; } } closedir($dh); } listDirRecursive(__DIR__); ?>

進階替代:SPL 迭代器 (推薦現代專案)

RecursiveDirectoryIterator + RecursiveIteratorIterator 提供物件導向、記憶體高效、可過濾、可排序的遍歷能力。

<?php
$iterator = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator(__DIR__, RecursiveDirectoryIterator::SKIP_DOTS),
    RecursiveIteratorIterator::SELF_FIRST
);

// 只列出 .php 檔案,按大小降序
$files = new RegexIterator($iterator, '/\.php$/i');
$files = new ArrayIterator(iterator_to_array($files));
$files->uasort(function($a, $b) { return $b->getSize() <=> $a->getSize(); });

foreach ($files as $file) {
    printf("%s (%s)
", $file->getPathname(), formatBytes($file->getSize())); } function formatBytes($bytes) { $units = ['B','KB','MB','GB']; $i = $bytes > 0 ? floor(log($bytes, 1024)) : 0; return round($bytes / (1024 ** $i), 2) . ' ' . $units[$i]; } ?>

常見坑點與最佳實踐

  • 編碼問題: Windows 下中文檔名可能為 GBK,需 iconv('GBK', 'UTF-8', $file) 轉碼後再輸出或操作。
  • 權限與錯誤: opendir 失敗會觸發 Warning,建議用 @opendir 配合 error_get_last() 或 is_readable() 預檢。
  • 效能: 大目錄 (>1萬檔) 下 scandir 佔用大量記憶體,readdir 迴圈或 SPL 迭代器更省記憶體。
  • 資源洩漏: 務必呼叫 closedir(),長時間運行腳本 (如守護進程) 未關閉會耗盡檔案描述符。
  • 符號連結: is_dir() 會跟隨連結,遞迴時需用 is_link() 判斷並決定是否進入,避免無限迴圈。

掌握 opendir 系列函數是 PHP 檔案系統操作的入門基石,實務上建議優先使用 SPL 迭代器獲得更健壯、可維護的代碼。

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