You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP遍历大量文件夹时部分图片/视频文件未列出求助

问题

我用以下PHP代码读取指定路径下各子文件夹中的PNG图片和MP4视频文件名,每个子文件夹仅包含1张图片和1个视频。当文件夹数量较少时代码运行正常,但遍历100个文件夹时,部分图片或视频会被遗漏,请求帮助排查问题。

<?php
$gfg_folderpath = "C:\wamp\www\Films/";

// CHECKING WHETHER PATH IS A DIRECTORY OR NOT
if (is_dir($gfg_folderpath)) {
    // GETTING INTO DIRECTORY
    $files = opendir($gfg_folderpath); {
        // CHECKING FOR SMOOTH OPENING OF DIRECTORY
        if ($files) {
            //READING NAMES OF EACH ELEMENT INSIDE THE DIRECTORY
            while (($gfg_subfolder = readdir($files)) !== FALSE) {
                // CHECKING FOR FILENAME ERRORS
                if ($gfg_subfolder != '.' && $gfg_subfolder != '..') {
                    // echo "SUBFOLDER--" .$gfg_subfolder . "<br>
                    // "."Files in ".$gfg_subfolder."--<br>";
                    
                    $dirpath = "C:\wamp\www\Films/" . $gfg_subfolder . "/";
                    // GETTING INSIDE EACH SUBFOLDERS
                    if (is_dir($dirpath)) {
                        $file = opendir($dirpath); {
                            if ($file) {
                                        
                                //READING NAMES OF EACH FILE INSIDE SUBFOLDERS
                                while (($gfg_filename = readdir($file)) !== FALSE) {

                                    $numbers = array();
                                    if ($gfg_filename != '.' && $gfg_filename != '..') {
                                        //  $mimeType = mime_content_type($gfg_filename);
                                        if(strtolower(end(explode(".",$gfg_filename))) =="png") {
                                            $vid= $gfg_filename . "<br>";
                                            $numbers[0]=$gfg_filename;
                    
                                        }
                                        if(strtolower(end(explode(".",$gfg_filename))) =="mp4") {
                                            $img= $gfg_filename . "<br>";
                                            $numbers[1]=$gfg_filename;
                                        }
                
                                        echo  $numbers[0]. "<br>".$numbers[1]. "<br>";      
                                    }
                
                                }
                            }
                        }
                    }
                    echo "<br>";
                }
            }
        }
    }
}
?>
  • 正常输出:每个子文件夹对应显示一行PNG文件名、一行MP4文件名,无遗漏
  • 异常输出:部分子文件夹仅显示其中一个文件,甚至两个文件都不显示
问题排查与修复

核心问题分析

  1. 数组重复初始化导致输出混乱:$numbers = array();写在子文件夹的文件循环内,每次读取一个文件就重置数组,导致第一次读取时只能赋值一个元素,空值直接输出;第二次读取才补全,但会重复输出,大量文件夹遍历易出现逻辑混乱。
  2. 未关闭目录句柄耗尽资源:每次opendir后未调用closedir释放资源,遍历大量文件夹时会耗尽系统允许的文件句柄数量,后续目录无法打开直接遗漏文件。
  3. 扩展名判断逻辑脆弱:用explode(".")获取扩展名,若文件名包含多个点(如image.v2.png),会导致扩展名判断错误。
  4. 路径分隔符混用有风险:Windows路径混用\和/,虽PHP兼容但存在潜在路径解析问题。

修复后的代码

<?php
// 使用DIRECTORY_SEPARATOR适配系统路径分隔符
$gfg_folderpath = "C:\wamp\www\Films" . DIRECTORY_SEPARATOR;

if (is_dir($gfg_folderpath)) {
    $mainDirHandle = opendir($gfg_folderpath);
    if ($mainDirHandle) {
        while (($gfg_subfolder = readdir($mainDirHandle)) !== false) {
            if ($gfg_subfolder === '.' || $gfg_subfolder === '..') {
                continue;
            }
            
            $dirpath = $gfg_folderpath . $gfg_subfolder . DIRECTORY_SEPARATOR;
            if (is_dir($dirpath)) {
                // 每个子文件夹仅初始化一次存储数组
                $mediaFiles = ['png' => '', 'mp4' => ''];
                $subDirHandle = opendir($dirpath);
                
                if ($subDirHandle) {
                    while (($gfg_filename = readdir($subDirHandle)) !== false) {
                        if ($gfg_filename === '.' || $gfg_filename === '..') {
                            continue;
                        }
                        
                        // 用pathinfo安全获取文件扩展名
                        $ext = strtolower(pathinfo($gfg_filename, PATHINFO_EXTENSION));
                        if ($ext === 'png') {
                            $mediaFiles['png'] = $gfg_filename;
                        } elseif ($ext === 'mp4') {
                            $mediaFiles['mp4'] = $gfg_filename;
                        }
                    }
                    // 及时关闭子目录句柄释放资源
                    closedir($subDirHandle);
                    
                    // 所有文件读取完成后统一输出
                    echo $mediaFiles['png'] . "<br>" . $mediaFiles['mp4'] . "<br><br>";
                }
            }
        }
        // 关闭主目录句柄
        closedir($mainDirHandle);
    }
}
?>

修复说明

  • 将数组初始化移到子文件夹循环内,确保每个子文件夹只初始化一次,读完所有文件后统一输出,避免重复输出和空值问题。
  • 每次opendir后调用closedir释放句柄,防止资源耗尽导致的目录无法打开。
  • 改用pathinfo获取扩展名,兼容含多个点的文件名,判断更可靠。
  • 使用DIRECTORY_SEPARATOR统一路径分隔符,适配不同操作系统,消除路径解析风险。

内容的提问来源于stack exchange,提问作者Habie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 00:20:53