2014-03-03 2 views
1

현재 PHP 프로젝트에서 사용자가 모두 함께 다운로드 할 수 있도록 일종의 아카이브에 여러 개의 PDF 파일을 묶어야합니다. zip이 가장 보편적이며 대부분의 비 IT-Windows 사용자가 알고 있기 때문에 zip 아카이브를 사용하려고합니다.PHP에서 큰 zip 아카이브 만들기

내 코드는 서버 메모리가 충분한 경우이 스크립트는 잘 작동 다음

$invoices = getRequestedInvoices(); // load all requested invoices, this function is just for demonstration 

// Create a temporary zip archive 
$filename = tempnam("tmp", "zip"); 
$zip = new \ZipArchive(); 
$zip->open($filename, \ZipArchive::OVERWRITE); 

foreach($invoices as $invoice) 
{ 
    // create the pdf file and add it to the archive 
    $pdf = new InvoicePdf($invoice); // this is derived from \ZendPdf\PdfDocument 
    $zip->addFromString($pdf->getFilename(), $pdf->render()); // for clarification: the getFilename method creates a filename for the PDF based on the invoice's id 
} 

$zip->close(); 

header('Content-Type: application/zip'); 
header('Content-Length: ' . filesize($filename)); 
header('Content-Disposition: attachment; filename="invoices.zip"'); 
readfile($filename); 
unlink($filename); 
exit; 

것 같습니다. 불행히도 우리의 생산 시스템은 매우 제한적이므로 스크립트는 단지 몇 개의 PDF 파일로만 작동하지만 대부분의 경우 메모리가 부족하고 중단됩니다. foreach 루프 끝 부분에서 unlink ($ pdf)를 추가해도 도움이되지 않았으므로 ZipArchive 객체가 메모리를 사용하고있는 것 같습니다.

프로젝트에 가능한 한 적은 의존성을 추가하려고합니다. 따라서 Zend Framework 2에서 PHP (PHP 5.4)의 고유 한 함수 또는 기능을 사용하여이 문제를 해결할 수 있기를 바랍니다. 몇 가지 방법을 찾고있었습니다. (zip : // 스트림 래퍼가 처음에는 좋았지 만 읽기 전용 임).하지만 zip 아카이브에서는 불가능한 것처럼 보입니다.

누구나 아이디어가 있습니까? 어쩌면 스트리밍을 허용하는 다른 종류의 널리 알려진 유형의 아카이브일까요? 압축은 필수적이지 않습니다.

+2

메모리가 부족하면 내장 된 zip 파일을 사용하지 마십시오. 'exec ("zip $ filename file1 file2 file3")'대신 PHP의 메모리 제한을받지 않아도됩니다. 쉘 인젝션 공격을 막기 위해 여러가지 파일명에 매우 조심해야하지만, 메모리 부족 오류로 PHP를 죽이지 않고서도 압축을 풀 수 있습니다. –

+0

나는 그것에 대해 생각했지만 플랫폼과 무관 한가? 우리가 다른 서버 (속성이 알려지지 않은)로 마이그레이션 할 때 미래를 염두에 두어야합니다. – Subsurf

+0

. 쉘을 다루기 시작하면 기본적으로 플랫폼 의존적입니다. –

답변

0

이 문제에 대한 빠른 해결책을 찾아야 했으므로 피하려고했지만 외부 종속성을 사용해야했습니다.

PHPZip 프로젝트 (https://github.com/Grandt/PHPZip)에서 ZipStream 클래스를 찾았으므로 제대로 작동합니다.

$zip = new \ZipStream("invoices.zip"); 

foreach($invoices as $invoice) 
{ 
    $pdf = new InvoicePdf($invoice); 
    $zip->addFile($pdf->render(), $pdf->getFilename()); 
} 

$zip->finalize(); 
exit; 
관련 문제