Управление архивом в памяти с помощью PHP (без создания временного файла на диске)

Я пытаюсь сгенерировать архив на лету в PHP и немедленно отправить его пользователю (не сохраняя его). Я подумал, что не нужно создавать файл на диске, поскольку отправляемые данные в любом случае не являются постоянными, однако после поиска в Интернете я не смог выяснить, как это сделать. Меня тоже не волнует формат файла.

Итак, вопрос в следующем:

Можно ли создавать и манипулировать файловым архивом в памяти внутри скрипта php, не создавая при этом временный файл?

26

Решение

У меня была та же проблема, но в конце концов я нашел несколько неясное решение и решил поделиться им здесь.

Я наткнулся на великого zip.lib.php/unzip.lib.php сценарии, которые идут с phpmyadmin и находятся в каталоге «библиотеки».

С помощью zip.lib.php сработал как брелок для меня:

require_once(LIBS_DIR . 'zip.lib.php');

...

//create the zip
$zip = new zipfile();

//add files to the zip, passing file contents, not actual files
$zip->addFile($file_content, $file_name);

...

//prepare the proper content type
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=my_archive.zip");
header("Content-Description: Files of an applicant");

//get the zip content and send it back to the browser
echo $zip->file();

Этот скрипт позволяет загружать zip-файлы без необходимости иметь файлы в виде реальных файлов или сохранять сам zip-файл в виде файла.

Жаль, что эта функциональность не является частью более общей библиотеки PHP.

Вот ссылка на zip.lib.php файл из источника phpmyadmin:
https://github.com/phpmyadmin/phpmyadmin/blob/RELEASE_4_5_5_1/libraries/zip.lib.php

ОБНОВИТЬ:
Убедитесь, что вы удалили следующую проверку из начала zip.lib.php, иначе скрипт просто завершится:

if (! defined('PHPMYADMIN')) {
exit;
}

ОБНОВИТЬ:
Этот код также доступен в проекте CodeIgniter:
https://github.com/patricksavalle/CodeIgniter/blob/439ac3a87a448ae6c2cbae0890c9f672efcae32d/system/helpers/zip_helper.php

43

Другие решения

что вы используете для создания архива? Возможно, вы сможете использовать поток php: // temp или php: // memory для чтения и записи в / из архива.

Увидеть http://php.net/manual/en/wrappers.php.php

3

Что касается вашего комментария, что php: // temp работает для вас, за исключением случаев, когда вы закрываете его, попробуйте держать его открытым, сбрасывая вывод, затем перематывайте его обратно в 0 и читайте его.

Смотрите здесь для большего количества примеров: http://us.php.net/manual/en/function.tmpfile.php

Также исследуем выходную буферизацию и захват: http://us.php.net/manual/en/function.ob-start.php

2

Вам нужно использовать ZipArchive::addFromString — если вы используете addFile() файл фактически не добавляется до тех пор, пока вы не закроете его. (ИМХО ужасная ошибка, что если вы пытаетесь переместить файлы в zip-файл и удалите их, прежде чем закрыть zip-файл …)
addFromString() Метод добавляет его в архив немедленно.

0

Здесь действительно проблема с производительностью, или это просто оскорбляет ваше чувство правильности? Многие процессы записывают временные файлы и удаляют их, и часто они никогда не попадают на диск из-за кэширования.

Tempfile автоматически удаляется при закрытии. Это природа.

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

  • используйте оперативный диск.
  • измените класс ziparchive, чтобы добавить метод, который делает все, что делает метод close (), Кроме на самом деле закройте файл. (Или добавьте параметр open-open, чтобы закрыть ()).
    Это может быть даже невозможно в зависимости от лежащих в основе библиотек C.
-7
По вопросам рекламы [email protected]