Я пытаюсь разархивировать архив 14 МБ с PHP с кодом как это:
$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);
}
Это перестало работать на моем localhost с пределом памяти 128 МБ с классиком"Allowed memory size of blablabla bytes exhausted
". На сервере у меня есть предел 16 МБ, есть ли лучший способ сделать это так, чтобы я мог вписаться в этот предел? Я не вижу, почему это должно выделить больше чем 128 МБ памяти.Заранее спасибо.
Решение: Я начал читать файлы в блоках 10 КБ, проблема, решенная с пиковым использованием памяти arnoud 1.5 МБ.
$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);
}
Для файла такого размера, возможно, лучше использовать shell_exec()
вместо этого:
shell_exec('unzip archive.zip -d /destination_path');
PHP должен не быть запущен в безопасном режиме, и у вас должен быть доступ к shell_exec и unzip, чтобы этот метод работал.
Обновление:
Учитывая, что инструменты командной строки недоступны, все, что я могу придумать, это создать сценарий и отправить файл на удаленный сервер, где инструменты командной строки доступны, извлечь файл и загрузить содержимое.
Просто потому, что размер zip-архива меньше предела памяти PHP и, возможно, распакованного тоже, не учитываются накладные расходы PHP в целом и, что более важно, память, необходимая для фактической распаковки файла, что хотя я не разбираюсь в сжатии, я ожидаю, что он может быть намного больше, чем окончательный размер в распакованном виде.