Intereting Posts
Преобразование файлов xlsx, docx, pdf в виде jpg-изображений с использованием PHP измерение прошедшего времени между сегментами кода в PHP Как избежать дублирования содержимого, хранящегося в базе данных MySQL, предоставленной пользователем Список файлов в каталоге и результат печати в формате JSON Как остановить сервер-отправленные события PHP – действие формы, вызывающее себя, как отображать все на одной странице? PHP – альтернативы runkit для перехвата вызовов методов woocommerce_thankyou вызывается 4 раза apc_store не работает между запросами Разбор строки SQL Как использовать htmlspecialchars, но разрешить только конкретный код HTML без преобразования? Как программно создавать базы данных MySQL на общих хостинговых планах Linux Вложенный, если он не работает в php, ничего не делает или идет в конец кода Как использовать глубокую ссылку на городской дирижабль с помощью PHP " child pid XXXX сигнал выхода Ошибка сегментации (11)" в apache error.log

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

Я пытаюсь создать архив на лету в 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: // для чтения и записи в / из архива.

См. 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() файл фактически не добавляется до тех пор, пока вы не закроете его. (Ужасная ошибка IMHO, что, если вы пытаетесь переместить файлы в zip, и вы удаляете их, прежде чем закрыть zip …)
Метод addFromString() немедленно добавляет его в архив.

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

Временной файл автоматически удаляется при закрытии. Вот в чем его природа.

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

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