Я пытаюсь сгенерировать архив на лету в PHP и немедленно отправить его пользователю (не сохраняя его). Я подумал, что не нужно создавать файл на диске, поскольку отправляемые данные в любом случае не являются постоянными, однако после поиска в Интернете я не смог выяснить, как это сделать. Меня тоже не волнует формат файла.
Итак, вопрос в следующем:
Можно ли создавать и манипулировать файловым архивом в памяти внутри скрипта php, не создавая при этом временный файл?
У меня была та же проблема, но в конце концов я нашел несколько неясное решение и решил поделиться им здесь.
Я наткнулся на великого 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
что вы используете для создания архива? Возможно, вы сможете использовать поток php: // temp или php: // memory для чтения и записи в / из архива.
Что касается вашего комментария, что 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-файл и удалите их, прежде чем закрыть zip-файл …)
addFromString()
Метод добавляет его в архив немедленно.
Здесь действительно проблема с производительностью, или это просто оскорбляет ваше чувство правильности? Многие процессы записывают временные файлы и удаляют их, и часто они никогда не попадают на диск из-за кэширования.
Tempfile автоматически удаляется при закрытии. Это природа.
Есть только два способа создать zip-файл в памяти и обслуживать его, и оба, вероятно, доставляют больше хлопот, чем они того стоят.