2012-07-18 89 views
1

嗨,Php下載zip檔案大檔案大小

我有一個窗體有多個複選框,它允許用戶選擇他們想要的小冊子,然後提示他們下載zip文件。 zip檔案下載功能正常運行。但我意識到下載會話將被終止而不下載整個文件(比如說8MB),並且下載的zip文件會被破壞。

參考下面的代碼,它不能解決問題。任何人都可以建議我需要查看哪些設置,或者我是否錯過了任何功能?

if($send) {  
    // Make sure program execution doesn't time out 
    // Set maximum script execution time in seconds (0 means no limit) 
    set_time_limit(0); 

    $post = $_POST;  
    $file_folder = "pdf/"; // folder to load files 
    $zip = new ZipArchive(); // Load zip library 
    $zip_name = "File-".time().".zip";   // Zip name 
    if($zip->open($zip_name, ZIPARCHIVE::CREATE)!==TRUE){  // Opening zip file to load files 
     $error .= "* Sorry ZIP creation failed at this time<br/>"; 
    } 
    foreach($post['brochure'] as $file){     
     $zip->addFile($file_folder.$file);   // Adding files into zip 
    } 
    $zip->close(); 
    if(file_exists($zip_name)){ 
     // set headers push to download the zip 
     header("Pragma: public"); 
     header("Expires: 0"); 
     header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 
     header("Cache-Control: public"); 
     header('Content-type: application/zip'); 
     header("Content-Transfer-Encoding: Binary"); 
     header('Content-Disposition: attachment; filename="'.$zip_name.'"'); 
     header("Content-Length: ".filesize($zip_name)); 
     readfile($zip_name); 
     // remove zip file is exists in temp path 
     unlink($zip_name); 

     $fp = @fopen($zip_name, "rb"); 
     if ($fp) { 
     while(!feof($fp)) { 
      print(fread($fp, 1024*8)); 
      flush(); // this is essential for large downloads 
      if (connection_status()!=0) { 
       @fclose($file); 
       die(); 
      } 
     } 
     @fclose($file); 
     } 
    } 

回答

1

而不是製作一個「readfile()」你試過這種解決方案嗎?

if(file_exists($zip_name)){ 
    header("Pragma: public"); 
    header("Expires: 0"); 
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 
    header("Cache-Control: public"); 
    header('Content-type: application/zip'); 
    header("Content-Transfer-Encoding: Binary"); 
    header('Content-Disposition: attachment; filename="'.$zip_name.'"'); 
    header("Content-Length: ".filesize($zip_name)); 

    echo file_get_contents($file); 
    exit 
} 

對我來說這很簡單,它在很多時候對我很好。

在這之後,我看到的問題是,你做:

unlink($zip_name); 
$fp = @fopen($zip_name, "rb"); 
if ($fp) { 
    ... 
} 

的這部分代碼不應該繼續下去,因爲你打開它之前,斷開鏈接的文件!

+0

嗨文森特,謝謝你的回覆。我面臨的問題是下載會話總是在幾秒鐘後終止而不下載整個zip文件。 – Xoozlez 2012-07-18 08:41:43

+0

它對我的解決方案做了同樣的事情? 如果下載是在它結束之前被截斷的,我不認爲它是一個PHP的問題:( – PoulsQ 2012-07-18 20:37:39

0

首先,您的if ($fp) {...}塊不應該被執行,因爲您之前已經完成了unlink($zip_name);。所以這個塊是沒用的。

次,我建議你用

ob_clean(); 
flush(); 
readfile($zip_name); 

這種替代

readfile($zip_name); 

將防止意外的邊框效果。最後,如果你仍然有損壞的檔案(我相信),那麼我認爲這是因爲在下載刷新之前,期間或之後發生了一些PHP錯誤(請注意,你的PHP代碼似乎並不像在下載之後結束,所以代碼可能會繼續,並且可能會發生一些錯誤)。如果發生這樣的PHP錯誤或PHP通知,PHP錯誤消息已經通過流式輸出。這很容易檢查:使用文本編輯器打開損壞的存檔以查看二進制內容,然後PHP錯誤消息應該在存檔的二進制內容的開始或最底部顯示爲清晰可讀。無需在HEXA模式下打開檔案。

+0

Hihi Skrol,我已經根據你的建議替換了編碼。但是我面對的問題是下載會話總是終止幾秒鐘後(下載的文件是est 2.5mb)而不下載整個zip文件(8mb) – Xoozlez 2012-07-18 08:44:18

+0

Hi Xoozlez,如果會話終止,你應該在zip二進制文件中有一個PHP通知,除非你避免了錯誤報告。如果您已經避免了錯誤報告,我建議您將它們打開以便能夠閱讀可能的錯誤。不過,使用'set_time_limit()'來延長會話時間。 – Skrol29 2012-07-18 09:19:41

0

設法解決我的問題與下面的代碼。基本上我不應該在調用fopen之前取消鏈接文件。

if($send) { 
    // Make sure program execution doesn't time out 
    // Set maximum script execution time in seconds (0 means no limit) 
    set_time_limit(0); 

    $post = $_POST;  
    $file_folder = "pdf/"; // folder to load files 
    $zip = new ZipArchive(); // Load zip library 
    $zip_name = "File-".time().".zip";   // Zip name 
    if($zip->open($zip_name, ZIPARCHIVE::CREATE)!==TRUE){  // Opening zip file to load files 
     $error .= "* Sorry ZIP creation failed at this time<br/>"; 
    } 
    foreach($post['brochure'] as $file){     
     $zip->addFile($file_folder.$file);   // Adding files into zip 
    } 
    $zip->close(); 
    if(file_exists($zip_name)){ 

     // set headers push to download the zip 
     header("Pragma: public"); 
     header("Expires: 0"); 
     header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 
     header("Cache-Control: public"); 
     header('Content-type: application/zip'); 
     header("Content-Transfer-Encoding: Binary"); 
     header('Content-Disposition: attachment; filename="'.$zip_name.'"'); 
     header("Content-Length: ".filesize($zip_name)); 

     //readfile($zip_name); 
     // remove zip file is exists in temp path 
     //unlink($zip_name); 

     $fp = @fopen($zip_name, "rb"); 
     if ($fp) { 
     while(!feof($fp)) { 
      echo fread($fp, 8192); 
      flush(); // this is essential for large downloads 
      if (connection_status()!=0) { 
       @fclose($zip_name); 
       die(); 
      } 
     } 
     @fclose($zip_name); 
     } 
     unlink($zip_name); 
    } 
}