2014-12-30 71 views
10

我需要在單個HTTP請求期間創建3個CSV文件(在內存中),將這些文件壓縮爲單個壓縮文件並將壓縮文件作爲HTTP響應返回。PHP在內存中創建多個CSV文件,然後壓縮

我有以下代碼來創建壓縮文件...

$files = array($file1, $file2); 
$zipname = 'file.zip'; 
$zip = new ZipArchive; 
$zip->open($zipname, ZipArchive::CREATE); 
foreach ($files as $file) { 
    $zip->addFile($file); 
} 
$zip->close(); 

header('Content-Type: application/zip'); 
header('Content-disposition: attachment; filename='.$zipname); 
header('Content-Length: ' . filesize($zipname)); 
readfile($zipname); 

不過,我不知道如何在內存中創建的CSV文件。

我該如何做到這一點?

回答

14

嘗試......

// some data to be used in the csv files 
$headers = array('id', 'name', 'age', 'species'); 
$records = array(
    array('1', 'gise', '4', 'cat'), 
    array('2', 'hek2mgl', '36', 'human') 
); 

// create your zip file 
$zipname = 'file.zip'; 
$zip = new ZipArchive; 
$zip->open($zipname, ZipArchive::CREATE); 

// loop to create 3 csv files 
for ($i = 0; $i < 3; $i++) { 

    // create a temporary file 
    $fd = fopen('php://temp/maxmemory:1048576', 'w'); 
    if (false === $fd) { 
     die('Failed to create temporary file'); 
    } 

    // write the data to csv 
    fputcsv($fd, $headers); 
    foreach($records as $record) { 
     fputcsv($fd, $record); 
    } 

    // return to the start of the stream 
    rewind($fd); 

    // add the in-memory file to the archive, giving a name 
    $zip->addFromString('file-'.$i.'.csv', stream_get_contents($fd)); 
    //close the file 
    fclose($fd); 
} 
// close the archive 
$zip->close(); 


header('Content-Type: application/zip'); 
header('Content-disposition: attachment; filename='.$zipname); 
header('Content-Length: ' . filesize($zipname)); 
readfile($zipname); 

// remove the zip archive 
// you could also use the temp file method above for this. 
unlink($zipname); 

我剛剛測試過我的機器上,它工作正常。

我用這個鏈接作爲參考,它可能有用。

MetaShock Reference

+0

非常有幫助。非常感謝。 – Cloud

1

您可以使用PHP的memory wrapper

$zipname = 'php://memory'; 

在具有/dev/shm文件系統,你能在那裏創建文件系統,它們將被保存在內存中,只有到當前進程訪問。發送後不要忘記刪除它們,Web服務器進程將繼續運行。

+0

這會支持多個文件嗎?例如... $ zipname1 ='php:// memory'; $ zipname2 ='php:// memory'; $ zipname3 ='php:// memory'; – fml

+0

每個'fopen('php:// memory',$ mode)'將在moemory文件中單獨打開。問題是他們沒有被命名,關閉文件指針會丟失寫入的內容。我不知道'ZipArchive'庫知道這是否是一個問題,可能你不應該調用'$ zip-> close()'而是其他的東西來獲取流。還有另一個解決方案,我會更新我的答案。 – Marek

相關問題