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

StackOverflow https://stackoverflow.com/questions/1189019

  •  19-09-2019
  •  | 
  •  

Вопрос

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

Итак, вопрос:

Можно ли создать и манипулировать архивом файла в памяти в сценарии PHP, не создавая Tempfile по пути?

Это было полезно?

Решение

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

Я пришел 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

Другие советы

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

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

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

Посмотрите здесь, чтобы узнать больше: http://us.php.net/manual/en/function.tmpfile.php

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

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

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

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

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

  • Используйте оперативную диск.
  • изменить класс Ziparchive, чтобы добавить метод, который делает все, что делает метод Close (), кроме на самом деле закройте файл. (Или добавьте параметр оставшегося отключения в Close ()).
    Это может быть даже невозможно в зависимости от базовых библиотек C.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top