Память архива php zip, оперативная память и максимальный размер файла

У меня есть папки с созданными пользователями изображениями, которые становятся довольно большими. При попытке заархивировать их я получаю ошибки вокруг zip-файлов размером 1,5 гигабайта.

Мои вопросы связаны с памятью, и я думаю, что php удерживает как открытый почтовый индекс, так и все изображения в памяти. Возможным решением, которое у меня есть, является отправка каждого изображения при загрузке в zip-файл в дополнение к соответствующей папке, пока это работает, но каковы пределы размера zip-файла, из того, что я могу найти около 4 ГБ. Как это влияет/взаимодействует с объемом оперативной памяти на сервере? \ и действительно ли ограничение составляет 4 ГБ, или я могу продолжать добавлять файлы в zip бесконечно, или мне нужно, чтобы скрипт проверял размер zip и если он превышает X gigs переименуйте его и создайте новый почтовый индекс. Я искал в Google и читал документацию, но нашел противоречивую информацию или неполную информацию, поэтому я ищу некоторые окончательные ответы и советы. Спасибо


person quick_learner42    schedule 20.04.2013    source источник
comment
сколько памяти могут иметь php-скрипты с вашей конфигурацией (см. php.ini ==> phpinfo()   -  person Dukeatcoding    schedule 20.04.2013
comment
вам лучше выполнить внешний zip через exec(). вы НЕ хотите, чтобы процесс php поглощал несколько гигов оперативной памяти.   -  person Marc B    schedule 20.04.2013
comment
@Duke 32 м из коробки, но я установил 128 м   -  person quick_learner42    schedule 20.04.2013
comment
Я бы тоже использовал exec() и zip, у меня всегда были проблемы только с php в таких замечательных файлах 128 м все еще мало   -  person Dukeatcoding    schedule 20.04.2013


Ответы (3)


Используйте php exec и вызовите инструмент zip в командной строке

 exec("tar -zcvf archive.tar.gz /folder/tozip");

Убедитесь, что пользователь, выполняющий файл php, имеет доступ к папке, которую вы хотите заархивировать.

И позаботьтесь о коде инъекции.

person Dukeatcoding    schedule 20.04.2013
comment
будет ли ограничение на количество файлов или размер конечного файла, который я могу заархивировать с помощью exec? - person quick_learner42; 20.04.2013
comment
обычно нет, пока файловая система может обрабатывать исходящий размер файла - person Dukeatcoding; 20.04.2013

Если вы все еще хотите использовать PHP ZipArchive, вы можете сделать несколько вещей, чтобы предотвратить определенные ограничения сервера/ОС:

  • Память Хотя в вашем случае это может показаться очевидным, я видел много примеров использования ZipArchive, использующих addFromString, чтобы добавить новый файл в архив. НЕ ДЕЛАЙТЕ! Это выделит память для открытия файла и сохранения в нем его содержимого, из-за чего у вас быстро закончится память, используйте добавить файл вместо этого. Также убедитесь, что вы освободили всю память, которая вам не нужна.

  • Время выполнения Увеличьте максимальное время выполнения вашего скрипта либо через php.ini, либо с помощью ini_set (например, ini_set('max_execution_time', 600); иметь максимальное время выполнения 10 минут)

  • Файловые дескрипторы Некоторые ОС имеют ограничения на количество открытых файлов, что может вызвать проблемы, поскольку PHP добавляет файлы в zip только после того, как вы закроете zip-файл. Чтобы предотвратить проблемы с количеством открытых файлов, просто закройте и снова откройте zip-файл каждые x файлов (например, каждые 1000), это заставит PHP сжимать и добавлять файлы, уже назначенные в архив.

  • Размер файла Могут быть некоторые ограничения размера файла ОС, больший размер файла также означает, что PHP требуется больше памяти для управления им, поэтому я лично предпочитаю использовать максимальный размер файла, после которого я просто открываю новый zip-файл, используя порядковый номер. Если точный размер файла для вас не имеет значения, вы можете просто посчитать размер файлов, идущих в архив, а затем переключаться после достижения определенного предела, или вы можете закрывать архив через каждые x файлов и проверять его размер на диске до решить, создавать новый архив или нет (помните, что файлы сжимаются только после того, как вы закроете архив)

Лично мне нравится ограничивать размер файла, получая размер файлов, поступающих в архив, и применяя к нему вероятный коэффициент сжатия, чтобы увидеть, когда, вероятно, будет достигнут максимальный размер архива (файлы jpg ~ 0,9, файлы zip = 1, текстовые файлы ~0,10, ...), а затем переключиться на следующий объем.

person Larzan    schedule 25.03.2014
comment
Будет ли addGlob() лучшим вариантом для добавления всех файлов из папки? - person Mirko; 16.02.2018

Поскольку поток или память могут все еще использоваться, вы должны "сбрасывать" архив из памяти после каждого/некоторых файлов:

$zip->close();
unset($zip);
$zip = new ZipArchive;
$zip->open("arch.zip");
person Artur Muszyński    schedule 15.06.2018