PHP на лету сбрасывает xml в zip-файл и загружает

Я создаю файл xml на основе информации из моей базы данных (формат xmltv). Эти xml-файлы могут быть довольно большими - обычно 25-70 МБ. Теперь я создаю файл xml на лету следующим образом:

$xmlWriter = new XMLWriter();
$xmlWriter->openURI('php://output');

и очистить цикл, чтобы предотвратить переполнение памяти. Я также устанавливаю заголовки для загрузки содержимого:

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $config->filename . '.xml"');

Я хотел бы иметь возможность заархивировать/сжать xml из-за размера. Возможно ли это на лету? Раньше я использовал PHPZip, который хорошо работает с файлами, но я не знаю, могу ли я записать вывод xml непосредственно в zip?


person Ernst Reidinga    schedule 10.10.2018    source источник
comment
См. stackoverflow.com/questions/29699777/ как один из вариантов   -  person i alarmed alien    schedule 14.10.2018
comment
Спасибо, но это не то, что я ищу, также awnser создает zip-файл, но не сжимает zip-файл. что мне нужно..   -  person Ernst Reidinga    schedule 14.10.2018
comment
Zip-файл по определению сжат.   -  person i alarmed alien    schedule 14.10.2018
comment
Это не совсем так. Zip - это контейнер, поэтому он упаковывает файлы. Он может быть сжат, но есть также zip-файлы, которые не сжимаются.   -  person Ernst Reidinga    schedule 14.10.2018


Ответы (1)


Если я правильно понял, цель состоит в том, чтобы динамически создавать данные, сжатые gzip, без создания файла на сервере. Это возможно с помощью deflate_init и deflate_add, но требуется PHP 7.

$gzip = deflate_init(ZLIB_ENCODING_GZIP, array('level' => 9));
$data = deflate_add($gzip, "my", ZLIB_NO_FLUSH);
$data .= deflate_add($gzip, "data", ZLIB_FINISH);

С помощью deflate_add мы можем добавлять больше данных любое количество раз (режим должен быть ZLIB_FINISH для последнего фрагмента).

Мы можем настроить этот метод, используя XMLWriter::openMemory (сохраняет данные в памяти) и XMLWriter::flush, чтобы архивировать элементы xml по мере их создания. , и создайте содержимое файла .gz на лету. Например, этот код:

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="file.gz"');

$xmlWriter = new XMLWriter();
$xmlWriter->openMemory();
$xmlWriter->startDocument('1.0', 'UTF-8');
$gzip = deflate_init(ZLIB_ENCODING_GZIP, array('level' => 9));

for ($i = 0; $i < 10; $i++) {
    $xmlWriter->writeElement("element", $i);
    $data = $xmlWriter->outputMemory();
    echo deflate_add($gzip, $data, ZLIB_NO_FLUSH);
}
echo deflate_add($gzip, "", ZLIB_FINISH);

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

person t.m.adam    schedule 16.10.2018
comment
Спасибо, кажется, это именно то, что мне нужно! Идеальный! Теперь я использую его почти таким же образом, когда я создаю xmlwriter, например: xmlWriter->openURI('php://output');, где я очищаю каждый раз, когда пишу элемент. - person Ernst Reidinga; 16.10.2018