4

I create a xml file based on information from my database (xmltv format). These xml files can be quite big - 25-70mb is normal. Now i create the xml file on the fly like this:

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

and flush through the loop to prevent memory overflow. I also set headers to push the content as download:

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

I would like to be able to zip/gzip the xml because of the size. Is this possible on the fly? I have used PHPZip before, which works good with files, but i dont know if i can write the xml output directly to the zip?

Ernst Reidinga
  • 175
  • 1
  • 11

1 Answers1

1

If I have understood correctly, the goal is to create gzip compressed data dynamically, without creating a file on the server. This is possible with deflate_init and deflate_add, but requires 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);

With deflate_add we can add more data any number of times (the mode should be ZLIB_FINISH for the last chunk).

We can adjust this method using XMLWriter::openMemory (stores the data in memory) and XMLWriter::flush, to zip the xml elements as they are produced, and create the contents of a .gz file on the fly. For example this code:

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);

creates xml elements, compresses and outputs them one by one, without using too much memory or any files.

t.m.adam
  • 14,050
  • 3
  • 25
  • 46
  • 1
    Thank you, this seems to be exactly what i need! Perfect! I am using it in a almost same way now, where i create xmlwriter like: `xmlWriter->openURI('php://output');` where i flush everytime i write an element. – Ernst Reidinga Oct 16 '18 at 15:16