PHP实现文件夹遍历与大小计算的核心代码示例

陆景行
陆景行
发布时间:2026-10-14| 4人浏览过
原创

本文将详细解析如何使用PHP原生函数实现文件夹的遍历输出与总大小计算。内容涵盖递归遍历目录树的逻辑构建、避免死循环的路径过滤技巧,以及将字节数转换为KB/MB/GB的单位显示函数,帮助开发者快速掌握文件系统操作的核心代码。

PHP文件夹操作的两种核心场景

在进行后端开发或服务器管理时,经常需要读取服务器上的文件信息。主要涉及两个需求:一是将目录下的所有文件和子目录以列表形式呈现(遍历);二是统计一个目录下所有文件的总体积(计算大小)。这两个操作通常都依赖于递归思想,因为文件夹内可能包含无限的子文件夹层级。

完整递归遍历目录并打印文件树

要实现类似Windows资源管理器那样的目录树效果,需要使用递归函数不断深入子目录。以下代码不仅遍历文件,还根据目录深度输出缩进,并在最后统计文件总数。

第1步:理解遍历函数的关键逻辑

目的: 获取指定路径下所有文件和文件夹的名称,并按层级缩进显示。 入口: scan_dir 函数接收目录名和缩进标识参数。 动作: 使用 opendir 打开句柄,通过 readdir 循环读取条目。注意必须剔除当前路径 . 和上级路径 ..,否则会导致无限递归并耗尽内存。

<?php 
//功能:遍历并打印指定目录下所有文件 
function scan_dir($dir_name,$dir_flag=1) { 
  static $FILE_COUNT=1;        //记录文件数目 初值为1 目录名称不记 
  $FILE_COUNT--;            //每调用一次scan_dir()函数自减1 
  @$dir_handle=opendir($dir_name);   //抑制错误信息显示 便于自定义错误显示 
  if(!$dir_handle) 
  die("目录打开错误!"); 
  while(false!==($filename=readdir($dir_handle))) //文件名为‘0'时,readdir返回 FALSE,判断返回值是否不全等 
  {                   
    $flag=$dir_flag;         //古怪的 is_dir($filename) ! $filename这个路径必须能够寻到!当$filename不存在或者不是目录时返回false 
    if($filename!='.'&&$filename!='..') 
    { 
      $FILE_COUNT++;          //不记录当前路径和上一级路径 
      while($flag>0&&--$flag)     //负数仍为真 
        echo '&nbsp'; 
      if(is_dir($dir_name.$filename)) //判断 是否为一个目录 
      { 
        echo '<strong>'."<a href=".$dir_name.$filename.">".$filename."</a></strong><br>"; 
        scan_dir($dir_name.$filename.'/',$dir_flag+1);   //$dir_flag标志目录树层次 
      } 
      else  
      { 
        echo "<a href=".$dir_name.$filename.">".$filename."</a><br>"; 
      } 
    } 
  } 
  closedir($dir_handle);         //关闭目录句柄 
  echo "文件总数:".$FILE_COUNT.'<br>'; 
} 

scan_dir('D:/AppServ/www/mytest/shopping/payment/'); 

/*总结:
1,关于路径 目录的路径末尾都加上 '/' 以便后面与文件名字符串连接 形成新的 路径字符串
2,目录遍历 这是一个关于树的问题
3,is_dir()函数第一个参数必须是一个能够识别的PATH否则会因目录不存在而返回一个false容易误解
得出 “这不是一个目录”的错误结论 形成逻辑上的错误
4,注意当前路径'.'和上一级路径'..'的剔除 否则 在递归环节造成死循环 直至内存耗尽出错。
5,dir_flag这个变量是记录树的深度 以便于目录分级分层输出                */
/*不足
1,输出排版不完善
2,逻辑与表示层混乱 不分明 大忌!
3,面向过程
*/

注意事项: 上述代码将HTML输出与逻辑处理混合在一起。在实际工程化应用中,建议将数据收集到数组后,再通过模板引擎渲染,以实现逻辑与视图分离。

单目录简单列出内容

如果不需要递归子目录,仅需列出当前一层的内容,可以使用更简单的非递归写法。这适用于生成简单的文件下载列表。

第2步:实现单层文件列表

重点: 同样需要忽略 ., .. 以及系统生成的隐藏文件如 Thumbs.db(Windows特有)。

// 列出目录内容 $dir 不要加 '/' 
function list_files($dir) 
{ 
  if(is_dir($dir)) 
  { 
    if($handle = opendir($dir)) 
    { 
      while(($file = readdir($handle)) !== false) 
      { 
        if($file != "." && $file != ".." && $file != "Thumbs.db") 
        { 
          echo '<a href="'.$dir.'/'.$file.'">'.$file.'</a><br>'."\n"; 
        } 
      } 
      closedir($handle); 
    } 
  } 
} 

list_files('D:/AppServ/www/mytest/shopping/payment');

递归计算文件夹总大小

计算目录大小是另一个高频场景,常用于清理空间预警或磁盘配额检查。核心思路是对每个子目录递归调用自身累加大小,对普通文件则调用 filesize()。

第3步:执行递归大小累加

参数: 传入完整的绝对路径。
步骤: 打开目录 -> 循环读取 -> 判断是否为目录 -> 是则递归 + 否则累加 filesize -> 关闭句柄。

<?php  
function getDirSize($dir) 
{ 
  $handle = opendir($dir); 
  while (false!==($FolderOrFile = readdir($handle))) 
  { 
    if($FolderOrFile != "." && $FolderOrFile != "..") 
    { 
      if(is_dir("$dir/$FolderOrFile")) 
      { 
        $sizeResult += getDirSize("$dir/$FolderOrFile"); 
      } 
      else 
      { 
        $sizeResult += filesize("$dir/$FolderOrFile"); 
      } 
    }   
  }  
  closedir($handle); 
  return $sizeResult; 
} 

//单位自动转换函数 
function getRealSize($size) 
{ 
  $kb = 1024;     //Kilobyte 
  $mb = 1024 * $kb;  //Megabyte 
  $gb = 1024 * $mb;  //Gigabyte 
  $tb = 1024 * $gb;  //Terabyte 
     
  if($size < $kb) 
  { 
    return $size." B"; 
  } 
  else if($size < $mb) 
  { 
    return round($size/$kb,2)." KB"; 
  } 
  else if($size < $gb) 
  { 
    return round($size/$mb,2)." MB"; 
  } 
  else if($size < $tb) 
  { 
    return round($size/$tb,2)." GB"; 
  } 
  else 
  { 
    return round($size/$tb,2)." TB"; 
  } 
} 

echo getRealSize(getDirSize('D:/AppServ/www/mytest/')); 

另一种紧凑写法如下,适合快速集成:

// get byte 
function dirsize($dir) 
{ 
  $handle=opendir($dir); 
  $size = 0; 
  while ( $file=readdir($handle) ) 
  { 
  if ( ( $file == "." ) || ( $file == ".." ) ) continue; 
  if ( is_dir("$dir/$file") ) 
  $size += dirsize("$dir/$file"); 
  else 
  $size += filesize("$dir/$file"); 
  } 
  closedir($handle); 
  return $size; 
} 

$big=dirsize(dirname($_SERVER['SCRIPT_FILENAME'])."/");
echo '('.$big.' bytes)';

常见问题与排错指南

在使用PHP文件系统函数时,以下几点容易导致BUG,需特别注意:

  • 路径斜杠问题: 拼接路径时务必确认父目录末尾是否有 /,例如 $dir . '/' . $file 或确保入参自带尾部斜杠,否则可能导致 is_dir 判断失败。
  • 权限拒绝: 如果脚本没有读取该目录的权限,opendir 可能返回 false 或触发警告。生产环境中建议使用 @ 符号抑制错误或显式检查返回值。
  • 大量文件性能: 对于包含成千上万个小文件的巨大目录,递归可能会导致栈溢出或响应超时。此时应考虑使用 glob 或迭代器模式替代深层递归。

以上就是PHP实现文件夹遍历与大小计算的详细内容,更多关于PHP目录操作技术的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。