PHP 即时刷新 xml 压缩文件并推送下载

PHP on the fly flush xml to zipfile and push download

我根据数据库中的信息创建了一个 xml 文件(xmltv 格式)。这些 xml 文件可能会很大 - 25-70mb 是正常的。现在我像这样即时创建 xml 文件:

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

并通过循环刷新以防止内存溢出。我还设置 headers 将内容推送为下载:

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

我希望能够 zip/gzip xml 因为大小。这是可能的吗?我以前用过 PHPZip,它对文件很有效,但我不知道我是否可以将 xml 输出直接写入 zip?

如果我没理解错的话,目标是动态创建 gzip 压缩数据,而不是在服务器上创建文件。这可以使用 deflate_init and 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 (stores the data in memory) and 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 个元素,一个一个地压缩和输出,不使用太多内存或任何文件。