Я пытаюсь создать архив на лету в PHP и немедленно отправить его пользователю (без сохранения). Я решил, что нет необходимости создавать файл на диске, поскольку данные, которые я отправляю, в любом случае не постоянны, однако при поиске в Интернете я не мог понять, как это сделать. Мне также не нужен формат файла.
Итак, вопрос:
Можно ли создавать и управлять файловым архивом в памяти в php-скрипте без создания временного файла на этом пути?
У меня была та же проблема, но в итоге я нашел несколько неясное решение и решил поделиться им здесь.
Я столкнулся с огромными zip.lib.php
/ unzip.lib.php
которые поставляются с phpmyadmin
и находятся в каталоге «libraries».
Использование 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
UPDATE: убедитесь, что вы удалили следующую проверку с начала zip.lib.php, так как иначе сценарий просто завершается:
if (! defined('PHPMYADMIN')) { exit; }
UPDATE: этот код доступен и для проекта CodeIgniter: https://github.com/patricksavalle/CodeIgniter/blob/439ac3a87a448ae6c2cbae0890c9f672efcae32d/system/helpers/zip_helper.php
что вы используете для создания архива? Возможно, вы сможете использовать память потока 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()
файл фактически не добавляется до тех пор, пока вы не закроете его. (Ужасная ошибка IMHO, что, если вы пытаетесь переместить файлы в zip, и вы удаляете их, прежде чем закрыть zip …)
Метод addFromString()
немедленно добавляет его в архив.
Есть ли проблема производительности здесь, или это просто оскорбляет ваше чувство правильности? Многие процессы записывают временные файлы и удаляют их, и часто они никогда не попадают на диск из-за кэширования.
Временной файл автоматически удаляется при закрытии. Вот в чем его природа.
Есть только два пути, которые я могу придумать, чтобы создать zip-файл в памяти и обслуживать его, и оба они, вероятно, больше проблем, чем они того стоят.