Unpacking large files using PHP

I am trying to unzip a 14 MB archive with PHP with code like this:

$zip = zip_open("c:\kosmas.zip"); while ($zip_entry = zip_read($zip)) { $fp = fopen("c:/unzip/import.xml", "w"); if (zip_entry_open($zip, $zip_entry, "r")) { $buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry)); fwrite($fp,"$buf"); zip_entry_close($zip_entry); fclose($fp); break; } zip_close($zip); } 

It does not work on my local host with a 128 MB memory limit with the classic " Allowed memory size of blablabla bytes exhausted ". I have a 16 MB limit on the server, is there a better way to do this so that I can fit into that limit? I do not understand why this should allocate more than 128 MB of memory. Thanks in advance.

Solution: I started reading files in 10Kb chunks, the problem was solved using arnoud 1.5MB peak memory.

  $filename = 'c:\kosmas.zip'; $archive = zip_open($filename); while($entry = zip_read($archive)){ $size = zip_entry_filesize($entry); $name = zip_entry_name($entry); $unzipped = fopen('c:/unzip/'.$name,'wb'); while($size > 0){ $chunkSize = ($size > 10240) ? 10240 : $size; $size -= $chunkSize; $chunk = zip_entry_read($entry, $chunkSize); if($chunk !== false) fwrite($unzipped, $chunk); } fclose($unzipped); } 
+6
php unzip
source share
4 answers

Why are you reading the entire file at once?

  $buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry)); fwrite($fp,"$buf"); 

Try to read small pieces and write them to a file.

+4
source share

Just because zip is smaller than the PHP memory limit, and possibly also unpacked, does not take into account the PHP overhead in general and, more importantly, the memory needed to actually unzip the file, which although I am not an expert with compression, I I expect it can be much larger than the final size of the decompressed file.

+1
source share

For a file of this size, it might be better to use shell_exec() :

 shell_exec('unzip archive.zip -d /destination_path'); 

PHP should not work in safe mode, and you must have shell_exec and unzip access for this method to work.

Update

Given that the command line tools are not available, all I can think of is to create a script and send the file to a remote server where the command line tools are available, extract the file and upload the contents.

0
source share
 function my_unzip($full_pathname){ $unzipped_content = ''; $zd = gzopen($full_pathname, "r"); while ($zip_file = gzread($zd, 10000000)){ $unzipped_content.= $zip_file; } gzclose($zd); return $unzipped_content; } 
0
source share

All Articles