【问题标题】:PHP Zip file download issuePHP Zip文件下载问题
【发布时间】:2013-11-02 12:22:54
【问题描述】:

我知道这个问题已经在这里被问过好几次了,我在这里使用了很多建议,但没有一个对我有用。

我的应用程序首先创建一个提要列表,然后用户选择要导出的提要。 php 文件为每个提要动态生成一个 csv 文件并将它们添加到 zip 文件中。最后,我只是关闭 zip 文件并使用readfile($zipfile) 阅读它。

在 Firefox 中使用 FireBug 对其进行调试时,响应标头与预期一致,并且响应也是二进制格式。但这不会在浏览器上生成保存对话框。

现在,如果我将要导出的 URL 直接粘贴到新窗口并单击,则会出现对话框。

那么这里缺少什么,为什么现有页面不能生成对话框?

这是我的代码。

公共函数 export_feeds($start, $end, $feedIds) { //要导出的文件名 $date = date('Y_m_j_H'); $fileName = 'Feeds_'.$date.'.zip'; // 我们创建 ZIP 文件 $zip = 新的 ZipArchive; $result_zip = $zip->open($fileName, ZipArchive::CREATE); // 我们打开文件 如果($result_zip === TRUE){ //遍历feedId的每一行并找到引擎。从特定引擎类调用导出函数并收集数据 $feedIdsArry = explode(":",$feedIds); foreach ($feedIdsArry as $value) { $qresult = $this->mysqli->query("SELECT engine, name FROM feeds WHERE `id` = '$value'"); $row = $qresult->fetch_array(); if ($row['engine']==Engine::TIMESTORE) { //$tableContent = $this->timestore->exportTable($value,$start,$end); $tableContent = $this->mysqltimeseries->exportTable($value,$start,$end); //临时锻炼 $tableContent = implode("\n", $tableContent); } if ($row['engine']==Engine::MYSQL) { $tableContent = $this->mysqltimeseries->exportTable($value,$start,$end); $tableContent = implode("\n", $tableContent); } $localFileName = $row['name'].'_'.$date.'.csv'; $zip->addFromString($localFileName, $tableContent); } $zip->close(); } 别的 { echo '失败,代码:' . $result_zip; } header("Pragma: public"); header("过期时间:0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("缓存控制:公共"); header("内容描述:文件传输"); header("内容类型:应用程序/zip"); header("内容配置:附件;文件名=".$fileName); header("内容传输编码:二进制"); header("内容长度:".filesize($fileName)); if(!file_exists($fileName)) { die('找不到压缩文件'); } 别的 { 读取文件($文件名); // 下载 ZIP 文件 } 出口; }

这是来自 Firebug 的响应标头

公共缓存控制 连接保活 内容描述文件传输 内容处置附件;文件名=Feeds_2013_10_24_14.zip 内容长度 1600 内容类型应用程序/强制下载 日期 2013 年 10 月 24 日星期四 01:39:38 GMT 过期 0 保活超时=5,最大值=100 语用公共 服务器 Apache/2.4.6 (Win32) PHP/5.5.4 X-Powered-By PHP/5.5.4 内容传输编码二进制

【问题讨论】:

  • 你是如何链接到下载的?
  • 没有下载zip文件的链接,点击导出按钮时,这是我调用的代码。

标签: php


【解决方案1】:

尝试使用这些标题:

原始回复

header('Cache-Control: public');  
header('Content-Description: File Transfer');  
header('Content-type: application/force-download');
header('Content-Disposition: attachment; filename="'.$filename.'"');

更新

您也可以尝试使用 cURL 代替 readfile(),例如:

function file_get_contents_curl($url) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //Set curl to return the data instead of printing it to the browser.
    curl_setopt($ch, CURLOPT_URL, $url);

    $data = curl_exec($ch);
    curl_close($ch);

    return $data;
}

然后:

if(!file_exists($fileName)) {
   die('Zip file not found');
}
else {
   $file_content = file_get_contents($fileName);  // To download the ZIP file
   header('Cache-Control: public');  
   header('Content-Description: File Transfer');  
   header('Content-type: application/force-download');
   header('Content-Disposition: attachment; filename="'.$filename.'"');
   echo $file_content;
}
exit;

【讨论】:

  • 我已经使用 Firebug 的响应标头编辑了我的帖子。还是不行。
  • 我也编辑了我的回复,也许使用 cURL 而不是 readfile() 可能会有所帮助。我不是 100% 确定,但你可以试一试。
  • 还是一样,我试试看是不是跟zip文件有关,只发csv文件。
  • 那么 csv 也不能正常工作,在所有浏览器中检查了同样的问题。
  • 我使用了您的原始代码,以及我的答案中包含的代码,并且两者都有效。唯一不同的是我的 PHP 版本(我怀疑这是问题的原因)和我的平台:Server:Apache/2.4.6 (Unix) PHP/5.5.1。我想知道你的 export 按钮是如何调用这个函数的?这确实很奇怪,理论上你所拥有的一切都应该“工作”。
【解决方案2】:

首先确保您没有发送除下载 zip 之外的某些标头。 我使用另一个标题:

        header('Content-Description: File Transfer');
        header('Content-type: application/zip');
        header('Content-Disposition: attachment; filename="'.($filename).'"');
        header("Content-Transfer-Encoding: binary");
        header('Expires: 0');
        echo($file_content);
        exit;

也许尝试做两个功能。一个用于创建 zip,第二个用于下载。 您可以添加一个带有下载按钮的弹出窗口吗?当您单击按钮时,您会调用第二个函数

【讨论】:

    猜你喜欢
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多