如何使用PHP从MySQL下载多格式文档并打包为ZIP?解决单列多路径打包仅含单个文件问题
问题分析与解决方案
我一眼就看出问题出在哪了——你在处理每个记录的多文件路径时,只把最后一个文件路径添加到了打包文件列表里,这就导致ZIP包里面的文件数量远少于预期。
问题根源
看你这段代码:
foreach($s as $key => $ew){ $submissionlink1 = 'document/'.$ew.''; }; array_push($files,$submissionlink1);
你在foreach循环里不断覆盖$submissionlink1的值,循环结束后才把这个变量(此时已经是最后一个文件的路径)加入$files数组。也就是说,每个数据库记录不管有多少个文件,最终只会把最后一个文件放进打包列表里。
修正后的完整代码
$sql = "SELECT * FROM submission INNER JOIN studentsubmission ON studentsubmission.SubmissionID = submission.SubmissionID WHERE submission.FacultyID= '$facultyId' AND studentsubmission.StudentSubmissionStatus='1'"; $result = $conn->query($sql); $files = []; // 初始化文件数组,避免未定义问题 if($result->rowCount() > 0){ while($row = $result->fetch()){ // 修正trim的参数,不需要转义逗号 $row['Document_url'] = trim($row['Document_url'], ','); $temp = explode(',',$row['Document_url'] ); $s = array_filter($temp); foreach($s as $key => $ew){ $submissionlink1 = 'document/'.$ew; // 把每个文件路径直接加入数组,而不是等循环结束再加 array_push($files,$submissionlink1); }; } } $zip = new ZipArchive(); $zip_name = time().".zip"; // Zip name $zip->open($zip_name, ZipArchive::CREATE); foreach($files as $a => $b){ if(file_exists($b)){ $zip->addFromString(basename($b), file_get_contents($b)); }else{ // 修正未定义的$d变量,改为当前文件路径$b echo "File does not exist: $b"; } } $zip->close();
关键修改点
- 把
array_push移到foreach循环内部:这样每个分割出来的文件路径都会被立即添加到$files数组中,不会丢失前面的文件。 - 修正
trim的参数:原代码里的trim($row['Document_url'],'\,')没必要转义逗号,直接用trim($row['Document_url'], ',')更规范。 - 初始化
$files数组:避免因为查询结果为空时$files未定义导致后续报错。 - 修正报错信息里的未定义变量:把
$d改成$b,这样能准确显示不存在的文件路径。
这样修改后,所有的文件路径都会被正确收集到$files数组里,打包出来的ZIP文件就会包含所有预期的文档了。
内容的提问来源于stack exchange,提问作者Zoey




