PHP Zip文件下载问题

时间:2013-10-24 00:56:37

标签: php

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

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

在firefox中使用FireBug进行调试时,响应标头符合预期,响应也采用二进制格式。但这不会在浏览器上生成保存对话框。

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

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

这是我的代码。

public function export_feeds($start, $end, $feedIds)
    {
        // Name of the file to export
        $date = date('Y_m_j_H');
        $fileName = 'Feeds_'.$date.'.zip';

        // We create the ZIP file
        $zip = new ZipArchive;
        $result_zip = $zip->open($fileName, ZipArchive::CREATE);    // We open the file
        if ($result_zip === TRUE) {

            //iterate through each row of the feedId and find the engine. Call the export function from the specifi engine class and collect the data
            $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); //temporary workout
                    $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();
        }
        else {
            echo 'Failed, code:' . $result_zip;
        }    

        header("Pragma: public");
        header("Expires: 0");
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Cache-Control: public");
        header("Content-Description: File Transfer");
        header("Content-type: application/zip");
        header("Content-Disposition: attachment; filename=".$fileName);
        header("Content-Transfer-Encoding: binary");
        header("Content-Length: ".filesize($fileName));

        if(!file_exists($fileName)) {
            die('Zip file not found');
        }
        else {
            readfile($fileName);  // To download the ZIP file
        }
        exit;

    } 

以下是来自Firebug的响应标头

Cache-Control   public
Connection  Keep-Alive
Content-Description File Transfer
Content-Disposition attachment; filename=Feeds_2013_10_24_14.zip
Content-Length  1600
Content-Type    application/force-download
Date    Thu, 24 Oct 2013 01:39:38 GMT
Expires 0
Keep-Alive  timeout=5, max=100
Pragma  public
Server  Apache/2.4.6 (Win32) PHP/5.5.4
X-Powered-By    PHP/5.5.4
content-transfer-encoding   binary

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分:0)

首先确保您没有发送除下载 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,第二个用于下载。 您可以添加带有按钮的弹出窗口进行下载吗?当你点击按钮时,你会调用第二个函数