Я создаю файл 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"');
Я хотел бы иметь возможность zip / gzip XML из-за размера. Это возможно на лету? Я использовал PHPZip раньше, который хорошо работает с файлами, но я не знаю, могу ли я записать вывод XML непосредственно в ZIP-файл?
Если я правильно понял, цель состоит в том, чтобы динамически создавать сжатые данные 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, сжимает и выводит их один за другим, не используя слишком много памяти или каких-либо файлов.
Других решений пока нет …