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

PHP压缩下载文件夹脚本生成0字节文件问题求助

PHP压缩大量文件后下载得到0字节Zip文件的问题

我写了一个PHP脚本用来压缩指定文件夹并提供下载,但当文件夹包含大量文件时,下载的zip文件大小为0字节。我已经用file_exists验证过文件路径是有效的,请问问题出在哪里?

原脚本代码:

<?php
// 定义要压缩的文件夹路径
$folder_path = '/CA11.2.4/logs/';

// 定义带时间戳的压缩文件名
$zip_file_name = 'logs_' . date('Ymd_His') . '.zip';

// 初始化ZipArchive实例
$zip = new ZipArchive();

// 打开压缩文件准备写入
if ($zip->open($zip_file_name, ZipArchive::CREATE) !== TRUE) {
    die ('无法创建压缩包');
}

// 将文件夹中的文件添加到压缩包
$dir = opendir($folder_path);
while ($file = readdir($dir)) {
    if (is_file($folder_path . $file)) {
        $zip->addFile($folder_path . $file, $file);
    }
}

// 关闭目录句柄
closedir($dir);

// 关闭压缩文件
$zip->close();

// 设置下载响应头
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="' . $zip_file_name . '"');
header('Content-Length: ' . filesize($zip_file_name));

// 输出压缩文件给客户端
readfile($zip_file_name);

// 删除服务器上的压缩文件(已注释)
//unlink($zip_file_name);

// 跳转回来源页面(已注释)
//header('Location: ' . $_SERVER['HTTP_REFERER']); 
?>

我最初怀疑路径未被识别,因此添加了以下代码片段验证,结果显示路径有效:

<?php
$path = '/path/to/folder/file.txt';

if (file_exists($path)) {
    echo '路径在服务器上存在';
} else {
    echo '路径在服务器上不存在';
}
?>

问题分析与解决方案

核心问题排查

  1. 未捕获addFile执行失败
    当文件夹文件数量大时,可能存在部分文件无法读取(权限不足、文件被占用、特殊字符文件名),但脚本没有检查addFile的返回值,一旦某个文件添加失败,后续流程可能异常中断,导致Zip文件未正常写入。

  2. 未处理子目录
    原脚本仅处理文件夹下的直接文件,若目标目录包含子文件夹,子目录内的文件不会被添加。如果根目录无文件,就会生成空Zip。

  3. 内存/执行时间限制
    压缩大量文件时,PHP可能因内存不足或执行超时,导致Zip文件未完成写入就终止,最终生成空文件。

  4. 文件大小缓存问题
    $zip->close()后系统可能还在刷新磁盘缓冲,此时调用filesize获取的大小可能不准确,甚至为0。

针对性解决方法

  1. 添加addFile错误检查
    修改循环逻辑,每次添加文件都验证结果,同时跳过.和..目录:

    while ($file = readdir($dir)) {
        if ($file === '.' || $file === '..') continue;
        $full_path = $folder_path . $file;
        if (is_file($full_path)) {
            if (!$zip->addFile($full_path, $file)) {
                error_log("添加文件失败: $full_path");
                // 可选择终止或继续,根据需求调整
                // die("添加文件失败: $full_path");
            }
        }
    }
    
  2. 递归遍历子目录
    编写递归函数处理所有层级的文件和目录:

    function addFolderToZip($folder, $zip, $parent_path = '') {
        $dir = opendir($folder);
        while ($file = readdir($dir)) {
            if ($file === '.' || $file === '..') continue;
            $full_path = $folder . '/' . $file;
            $relative_path = $parent_path . $file;
            if (is_file($full_path)) {
                $zip->addFile($full_path, $relative_path);
            } elseif (is_dir($full_path)) {
                $zip->addEmptyDir($relative_path);
                addFolderToZip($full_path, $zip, $relative_path . '/');
            }
        }
        closedir($dir);
    }
    
    // 替换原有的文件添加代码
    addFolderToZip($folder_path, $zip);
    
  3. 调整PHP运行参数
    在脚本开头增加内存和执行时间限制:

    ini_set('memory_limit', '256M'); // 根据实际文件大小调整
    set_time_limit(300); // 设置为5分钟,避免超时中断
    
  4. 刷新文件状态缓存
    在$zip->close()后刷新文件状态,确保获取正确的文件大小:

    $zip->close();
    clearstatcache(true, $zip_file_name); // 刷新指定文件的状态缓存
    
  5. 检查权限设置
    确保PHP进程对/CA11.2.4/logs/下的所有文件有读取权限,同时对脚本所在目录有写入权限(用于生成Zip文件)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 23:42:30