小天管理 发表于 2024年9月11日 发表于 2024年9月11日 我用的是 php ,问了一圈 AI ,告诉我使用 ZipStream ,但是我试了同样需要等待压缩的时候非常久,而不是像群晖 NAS 那样,立即开始下载,且浏览器不显示最终文件大小。 请问 v 友这是如何做到的 public function downloadFolderNew() { $path = $this->request->param("path", ""); if (!empty($path)) { // 将路径转换为项目的公共路径 $path = str_replace("D:\\phpproject\\test\\public\\", public_path(), $path); } if (!is_dir($path)) { $this->error("路径不存在"); } $fileName = $this->request->param("file_name", "") ?: uniqid(); $zipFileName = $fileName . ".zip"; // 设置响应头 header('Content-Type: application/zip'); header('Content-Disposition: attachment; filename="' . $zipFileName . '"'); header('X-Accel-Buffering: no'); // 关闭 Nginx 的输出缓冲 // 禁用输出缓冲区 if (ob_get_level()) { ob_end_clean(); } // 立即输出部分内容,浏览器开始下载 echo "\xEF\xBB\xBF"; // 避免 PHP 输出缓冲,立即开始下载 flush(); // 创建一个 ZIP 流 $zip = new ZipStream\ZipStream(null, [ 'outputStream' => 'php://output' // 将输出直接定向到浏览器 ]); // 递归添加文件夹内容到 ZIP $this->addFolderToZip($zip, $path, ''); // 结束 ZIP 流 $zip->finish(); exit(); } private function addFolderToZip($zip, $folder, $zipPath) { // 创建迭代器,遍历文件夹中的文件 $files = new \RecursiveIteratorIterator( new \RecursiveDirectoryIterator($folder, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::LEAVES_ONLY ); foreach ($files as $file) { $filePath = $file->getRealPath(); $relativePath = substr($filePath, strlen($folder) + 1); // 获取文件相对路径 if (!$file->isDir()) { // 确保文件路径和内容正确添加到 ZIP 中 $zip->addFileFromPath($zipPath . $relativePath, $filePath); } // 刷新输出缓冲,逐步发送数据到浏览器 flush(); } }
已推荐帖子