Распаковки больших файлов с помощью PHP
Я пытаюсь распаковать архив 14MB с 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 с ограничением памяти 128MB с классическим"Allowed memory size of blablabla bytes exhausted
". На сервере у меня есть ограничение 16MB, есть ли лучший способ сделать это, чтобы я мог вписаться в этот предел? Я не понимаю, почему это должно выделять больше, чем 128MB памяти. Спасибо заранее.
устранение: Я начал читать файлы в кусках 10Kb, проблема решена с использованием пиковой памяти arnoud 1.5 MB.
$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);
}
4 ответов
зачем Вы читаете весь файл сразу?
$buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
fwrite($fp,"$buf");
попробуйте прочитать небольшие куски и записать их в файл.
просто потому, что zip меньше, чем ограничение памяти PHP , и, возможно, распаковка также не учитывает накладные расходы PHP в целом и, что более важно, память, необходимая для фактического распаковки файла, что, хотя я не эксперт по сжатию, я ожидаю, что может быть намного больше, чем окончательный размер распаковки.
для файла такого размера, возможно, лучше использовать shell_exec()
вместо:
shell_exec('unzip archive.zip -d /destination_path');
PHP должен не работает в безопасном режиме, и вы должны иметь доступ к shell_exec и распаковать этот метод для работы.
обновление:
учитывая, что инструменты командной строки недоступны, все, что я могу придумать, это создать скрипт и отправить файл на удаленный сервер, где инструменты командной строки are доступно, извлеките файл и загрузите его содержимое.
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;
}