PHP递归实现目录操作:遍历、复制、删除与大小计算

Owen
Owen
发布时间:2026-10-15| 3人浏览过
原创

在PHP开发中,经常需要处理复杂的文件系统任务,如批量迁移备份、清理临时文件或统计资源占用。由于文件系统呈现树状结构,递归是解决此类问题的核心逻辑。本文将通过四个独立且完整的代码示例,演示如何遍历、复制、删除目录以及计算其总大小,帮助开发者掌握opendir、readdir、is_dir等关键函数的组合应用。

准备条件与环境说明

所有示例均基于标准PHP环境运行,无需额外扩展。执行涉及删除或覆盖的操作前,务必确认目标路径无重要数据,因为递归删除通常是不可逆的。代码中的路径为相对路径(如./final/factapplication),实际使用时请根据服务器文件结构调整。

第1步:递归遍历并列出目录内容

目的:深入指定目录及其子目录,输出所有非隐藏文件的名称。

原理:通过opendir打开句柄,readdir循环读取文件名,利用is_dir判断类型。若为目录则调用自身继续深入,若为文件则直接打印。

<?php
header("content-type:text/html;charset=utf-8");
$dirname = "./final/factapplication";

function listdir($dirname) {
    $ds = opendir($dirname);
    while (false !== ($file = readdir($ds))) {
        $path = $dirname.'/'.$file;
        if ($file != '.' && $file != '..') {
            if (is_dir($path)) {
                listdir($path); // 递归进入子目录
            } else {
                echo $file."<br>"; // 输出文件名
            }
        }
    }
    closedir($ds);
}
listdir($dirname);
?>

完成状态:控制台输出目标目录下的所有文件名,包含深层嵌套结构中的文件。

第2步:递归复制整个目录结构

目的:将源目录$srcdir下的所有文件和子目录完整克隆至$dstdir。

要点:使用mkdir创建目标根目录,在遇到子目录时先创建对应的目标子目录,再递归处理;遇到文件时使用copy()进行物理拷贝。

<?php
$srcdir = "../fileupload";
$dstdir = "b";

function copydir($srcdir, $dstdir) {
    mkdir($dstdir);
    $ds = opendir($srcdir);
    while (false !== ($file = readdir($ds))) {
        $path = $srcdir."/".$file;
        $dstpath = $dstdir."/".$file;
        if ($file != "." && $file != "..") {
            if (is_dir($path)) {
                copydir($path, $dstpath); // 递归复制子目录
            } else {
                copy($path, $dstpath); // 复制单个文件
            }
        }
    }
    closedir($ds);
}
copydir($srcdir, $dstdir);
?>

风险提示:copy()若目标路径已存在同名文件可能被覆盖,执行前建议检查目标位置状态。

第3步:递归删除目录及其所有内容

目的:清空指定目录,包括其中的所有文件和子文件夹,最后移除目录本身。

逻辑:遵循“自底向上”原则,即先删除子目录内的文件,再删除子目录,最后删除当前层级的文件,直至返回rmdir删除空目录。

<?php
$dirname = 'a';

function deldir($dirname) {
    $ds = opendir($dirname);
    while (false !== ($file = readdir($ds))) {
        $path = $dirname.'/'.$file;
        if($file != '.' && $file != '..') {
            if (is_dir($path)) {
                deldir($path); // 递归删除子目录
            } else {
                unlink($path); // 删除具体文件,注意需带完整路径
            }
        }
    }
    closedir($ds);
    return rmdir($dirname); // 删除当前空目录
}
deldir($dirname);
?>

关键细节:unlink($path)必须传入完整的文件路径参数,仅传文件名可能导致在当前脚本目录下误删文件。此操作具有高风险,生产环境中慎用。

第4步:递归计算文件夹总大小

目的:统计指定目录及其子目录下所有文件的字节总和。

难点:递归函数通常逐层返回,若直接在每次调用中返回累计值容易导致重复计算或层级丢失。此处使用static修饰变量$tot,使其在所有递归层级中共享内存空间,累加后统一返回。

<?php
$dirname = "a";

function dirsize($dirname) {
    static $tot; // 静态变量保持跨层级累加
    $ds = opendir($dirname);
    while (false !== ($file = readdir($ds))) {
        $path = $dirname.'/'.$file;
        if ($file != '.' && $file != '..') {
            if(is_dir($path)) {
                dirsize($path); // 递归进入子目录累加
            } else {
                $tot = $tot + filesize($path); // 累加文件大小
            }
        }
    }
    closedir($ds);
    return $tot;
}
echo dirsize($dirname);
?>

总结与最佳实践

上述四个案例展示了PHP处理树形文件系统的基本范式。无论是listdir的纯展示,还是deldir的结构化清理,核心都在于正确判断is_dir并合理处理递归出口。在实际应用中,建议增加权限检查(如writable测试)以提升脚本健壮性。

以上就是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 算法库。