2010-06-20 46 views
16

我有一個PHP腳本,可以即時創建zip文件並強制瀏覽器下載zip文件。問題是:我可以直接將zip文件寫入連接到用戶瀏覽器的輸出流,而不是先將它作爲真正的文件保存在服務器上,然後發送文件?PHP中的Zip流

在此先感謝。

+1

的這個問題的答案就在這裏:http://stackoverflow.com/a/4357904/416630 – Lee 2012-11-23 18:12:26

回答

5

如果您使用的是zip extension,答案似乎是「不」。 close method in the ZipArchive class是觸發寫入的東西,它似乎要寫入文件。你可能運用Streams來模擬一個文件,但是你將整個東西保存在內存中,並且在你添加完文件之前仍然無法發送它。

如果您在同時具有一個用戶等待的zip文件被創建與超時或其他問題的問題,嘗試了多步下載過程:

  1. 用戶挑選不管他們挑來創建zip
  2. 它們被帶到一個狀態頁面,該頁面使用ajax調用來在後臺實際構建zip文件。一個漂亮的,分散注意力的動畫應該引起他們的注意。
  3. 後臺進程構建zip後,用戶被重定向到執行下載/重定向到文件的腳本。
11

如果你的Web服務器運行Linux,那麼你可以做流而不產生的臨時文件。在win32下,你可能需要使用Cygwin或類似的東西。

如果使用「 - 」作爲zip文件名,它將壓縮爲stdout。從那裏,很容易使用popen()重定向該流。 「-q」參數簡單地告訴zip不輸出它通常會出現的狀態文本。有關更多信息,請參見zip(1)手冊頁。

<? 
    $zipfilename = "zip_file_name.zip"; 

    if(isset($files)) unset($files); 

    $target = "/some/directory/of/files/you/want/to/zip"; 

    $d = dir($target); 

    while(false !== ($entry = $d->read())) 
    { 
     if(substr($entry, 0, 1) != "." && !is_dir($entry)) 
     { 
     $files[] = $entry; 
     } 
    } 

    header("Content-Type: application/x-zip"); 
    header("Content-Disposition: attachment; filename=\"$zipfilename\""); 

    $filespec = ""; 

    foreach($files as $entry) 
    { 
     $filespec .= "\"$entry\" "; 
    } 

    chdir($target); 

    $stream = popen("/usr/bin/zip -q - $filespec", "r"); 

    if($stream) 
    { 
     fpassthru($stream); 
     fclose($stream); 
    } 
?> 
1

是的,你可以使用這個混帳代表直接流的壓縮到客戶端:Zip Stream Large Files

+0

似乎不能在windows下工作 – Jerry 2016-07-21 10:26:05