PHP从MySQL导出PDF打包Zip自动下载:空文件问题求助
问题分析与修复方案
核心问题点
- SQL查询未绑定有效参数:原查询硬编码了
softwareID = 918,导致用户提交的ID完全没生效,获取的文件列表大概率为空或与需求不符。 - 文件路径缺失:数据库仅存文件名,实际文件在服务器
addendums文件夹下,直接用文件名调用addFile会找不到文件,Zip自然为空。 - GROUP_CONCAT存在隐患:若文件名包含逗号,
explode(",", $files)会分割出无效文件名,导致添加失败。 - 无错误校验机制:未检查Zip创建、文件读取的返回状态,无法定位失败原因。
修复后的完整代码
<?php // 开启输出缓冲,避免header报错 ob_start(); if (isset($_POST["submit"]) || isset($_POST["submit_x"])) { // 校验提交的ID参数 if (!isset($_POST['softwareID']) || !is_numeric($_POST['softwareID'])) { die("无效请求参数"); } $softwareID = (int)$_POST['softwareID']; // 修正SQL查询:使用占位符绑定参数,放弃GROUP_CONCAT改用逐行读取 $exhibitee_export = new WA_MySQLi_RS("exhibitee_export", $sdpc_i, 0); $exhibitee_export->setQuery(" SELECT signed_addendum_file FROM mspa.data t1 LEFT JOIN mspa.addendums_data t2 ON t2.dataID = t1.dataID WHERE (t1.statusID = 1 OR t1.statusID = 15) AND t1.softwareID = ? AND t2.signed_addendum_file IS NOT NULL "); $exhibitee_export->bindParam("i", $softwareID); $exhibitee_export->execute(); // 生成Zip文件名(替换空格为下划线,避免浏览器解析问题) $zipname = "export_" . date('Y.m.d_H.i.s') . ".zip"; $zip = new ZipArchive; $openStatus = $zip->open($zipname, ZipArchive::CREATE | ZipArchive::OVERWRITE); if ($openStatus !== true) { die("创建Zip文件失败,错误码:$openStatus"); } $hasValidFiles = false; // 遍历查询结果,逐个添加有效文件 while (!$exhibitee_export->atEnd()) { $filename = $exhibitee_export->getColumnVal("signed_addendum_file"); // 拼接文件绝对路径,确保PHP能找到目标文件 $fullPath = __DIR__ . "/addendums/" . $filename; // 检查文件是否存在且可读 if (file_exists($fullPath) && is_readable($fullPath)) { if ($zip->addFile($fullPath, $filename)) { $hasValidFiles = true; } else { error_log("无法添加文件到Zip:$fullPath"); } } else { error_log("文件不存在或不可读:$fullPath"); } $exhibitee_export->moveNext(); } $zip->close(); // 处理无有效文件的情况 if (!$hasValidFiles) { unlink($zipname); die("没有可导出的有效文件"); } // 输出下载响应头 header('Content-Type: application/zip'); header('Content-Disposition: attachment; filename="' . basename($zipname) . '"'); header('Content-Length: ' . filesize($zipname)); header('Pragma: no-cache'); header('Expires: 0'); // 输出Zip文件并清理临时文件 readfile($zipname); unlink($zipname); exit; } ob_end_flush(); ?>
关键修复说明
- SQL查询修正:移除硬编码的ID值,改用占位符绑定用户提交的参数,确保查询结果准确;同时放弃
GROUP_CONCAT,避免文件名含逗号导致的分割错误。 - 文件路径处理:使用
__DIR__拼接绝对路径,彻底解决文件找不到的问题。 - 错误校验:添加参数校验、Zip创建状态校验、文件存在性校验,避免无效操作生成空Zip。
- 下载优化:替换文件名中的空格为下划线,避免部分浏览器解析文件名出错;添加缓存控制头,避免下载异常。
- 临时文件清理:下载完成后自动删除生成的Zip文件,避免占用服务器磁盘空间。
内容的提问来源于stack exchange,提问作者user2048308
相关产品推荐
相关产品推荐

