簡體   English   中英

PHP下載腳本在Mac上創建了無法讀取的ZIP文件

[英]PHP Download Script Creates Unreadable ZIP File on Mac

作為參考,我已經閱讀並嘗試了這些和其他幾個線程的答案:

使用php創建和提供壓縮文件

打開下載的zip文件會創建cpgz文件嗎?

我的服務器上有一個zip文件。

  1. 當我使用Filezilla將那個Zip文件從服務器移動到Mac時,可以正常打開它。

  2. 當我使用此PHP代碼將Zip文件下載到我的Linux機器時,它將正常打開。

  3. 當我使用此PHP代碼通過Safari或Firefox將Zip文件下載到Mac時,出現錯誤消息,提示“解壓縮失敗”或“檔案的結構已損壞”,或者得到了.cpgz文件-我相信表示計算機正在壓縮文件,而不是解壓縮文件。

這是我用來傳遞zip文件的PHP代碼。

$zipname = "myfile.zip";
$zippath = "/path/to/" . $zipname;

      if ($downloadzip = fopen ($zippath, "r")) {
            $fsize = filesize($zippath);

            header("Content-type: application/zip");
            header("Content-Disposition: attachment; filename=\"".$zipname."\"");
            header("Content-length: $fsize");
            header('Content-Transfer-Encoding: binary');
            #header("Cache-control: private"); //use this to open files directly

            echo fpassthru($downloadzip); // deliver the zip file

        }
        fclose ($downloadzip);

我發現一些頭文件有效。 我真的不知道或不在乎它為什么起作用,我很高興它能起作用...我嘗試了很多不同的東西,.htaccess文件,php.ini / zlib設置。

答案是http://perishablepress.com/http-headers-file-downloads/

$zipName = 'myfile.zip';
$zipPath = 'mydirectory/' . $zipName;


    if (file_exists($zipPath)) {

        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/octet-stream");
        header("Content-Disposition: attachment; filename=\"".$zipName."\"");
        header("Content-Transfer-Encoding: binary");
        header("Content-Length: ".filesize($zipPath));
        ob_end_flush();
        @readfile($zipPath);
}

這是有效的

$zipName = 'myfile.zip';
$zipPath = 'mydirectory/' . $zipName;

    if (file_exists($zipPath)) {

        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/octet-stream");
        header("Content-Disposition: attachment; filename=\"".$zipName."\"");
        header("Content-Transfer-Encoding: binary");
        header("Content-Length: ".filesize($zipPath));
        ob_end_flush();
        @readfile($zipPath);
}

通常,此問題是由在讀取文件之前已打印或回顯頁面的多余字符引起的。 即使有空間也會導致故障。 要解決該問題,請調用ob_end_clean(); 在讀取文件之前,這將清除輸出緩沖區並關閉緩沖。

但是請記住,您可以嵌套輸出緩沖區,這也會破壞您的下載(請向Vladamir表示感謝)。 因此,要清除輸出緩沖區,請在讀取文件之前完全運行此命令:

while (ob_get_level()) {
    ob_end_clean();
}    

這將清除您的整個緩沖區,並且您不會有任何多余的字符來破壞您的下載。

對於那些感興趣的人,我在下面粘貼了我的下載腳本。 我的zip文件現在可以完美下載了,到目前為止效果很好。

if (file_exists($zip_file_path)) {

        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");
        //We can likely use the 'application/zip' type, but the octet-stream 'catch all' works just fine.  
        header("Content-type: application/octet-stream");
        header("Content-Disposition: attachment; filename='$zip_file_name'");
        header("Content-Transfer-Encoding: binary");
        header("Content-Length: ".filesize($zip_file_path));

        while (ob_get_level()) {
             ob_end_clean();
        }

        @readfile($zip_file_path);

        exit;
}

好吧,我想您知道您的$ fsize變量沒有被寫入該標頭,因為它用引號引起來。 您可以嘗試這樣的事情:

header('Cache-Control: public');
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename=\"".$zipname."\"');
header('Content-Type: application/zip');

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM