Распаковки больших файлов с помощью 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;

}