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

PHP递归删除多目录文件时如何保留指定图片避免误删

现有代码失效原因

你的代码会无差别删除所有内容,核心是两个逻辑错误:

  • 自定义的rrmdir函数是标准的递归强制删目录逻辑,内部没有任何保留指定文件的判断,只要传入目录路径,就会删除目录下所有内容、最后删除目录本身,完全忽略$filesToKeep的规则。
  • 外层循环只判断了根目录下的条目名称是否在保留列表中,不会进入子目录做文件名匹配。你根目录下的子文件夹名称显然不会是partner-profil-480.jpg,所以所有子文件夹都会被直接传入rrmdir整体删除,最终所有内容被清空。
修正后的实现方案

逻辑调整为:递归遍历每个子文件夹,逐个判断文件是否需要保留,非保留文件直接删除,清理完成后可选择删除空目录,不会直接删除整个目录树。

<?php
// 定义需要保留的文件名,所有子目录下同名文件都会被保留
$filesToKeep = [
    'partner-profil-480.jpg'
];

/**
 * 递归清理指定目录
 * @param string $dir 待清理目录路径
 * @param array $keepFiles 需要保留的文件名列表
 */
function cleanDir(string $dir, array $keepFiles): void
{
    if (!is_dir($dir)) return;
    $entries = scandir($dir);
    foreach ($entries as $entry) {
        if ($entry === '.' || $entry === '..') continue;
        $fullPath = $dir . DIRECTORY_SEPARATOR . $entry;
        if (is_dir($fullPath)) {
            // 先递归清理子目录内容
            cleanDir($fullPath, $keepFiles);
            // 子目录清理后为空则删除,不需要删空目录可注释以下3行
            if (count(scandir($fullPath)) === 2) {
                rmdir($fullPath);
            }
        } else {
            // 文件不在保留列表则删除
            if (!in_array($entry, $keepFiles)) {
                unlink($fullPath);
            }
        }
    }
}

// 遍历根目录下所有子文件夹执行清理
$rootEntries = glob('*');
foreach ($rootEntries as $entry) {
    if (is_dir($entry)) {
        cleanDir($entry, $filesToKeep);
    }
    // 若需要同时清理根目录下的非保留文件,取消下方注释即可
    // else {
    //     if (!in_array($entry, $filesToKeep)) {
    //         unlink($entry);
    //     }
    // }
}
?>
使用说明
  • 保留规则匹配文件名,不限制文件所在路径,所有子目录下只要文件名和$filesToKeep内的条目一致,就不会被删除。
  • 代码不会直接删除整个目录,不会出现之前整目录被清空的问题。
  • 默认会删除清理后没有任何文件的空目录,如果需要保留空目录,注释掉代码中对应rmdir($fullPath)的段落即可。
  • 默认仅清理子文件夹内的内容,不会修改根目录下的文件;如果需要根目录也执行相同的清理规则,打开代码中对应的注释段即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 03:01:43