Манипулировать архивом в памяти с помощью PHP (без создания временного файла на диске)
Вопрос
Я пытаюсь сгенерировать архив на лету в 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: // память для чтения и записи в/из архива.
Что касается вашего комментария о том, что 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.