我根据数据库中的信息创建了一个 xml 文件(xmltv 格式)。这些 xml 文件可能很大 - 25-70mb 是正常的。现在我像这样动态创建 xml 文件:
$xmlWriter = new XMLWriter();
$xmlWriter->openURI('php://output');
并通过循环flush来防止内存溢出。我还设置了标题以将内容推送为下载:
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $config->filename . '.xml"');
由于大小原因,我希望能够对 xml 进行 zip/gzip 压缩。这是可能的吗?我以前用过 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 我们可以添加更多的数据任意次(最后一个 block 的模式应该是 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 元素,将它们一个一个地压缩和输出,而不使用太多内存或任何文件。
关于PHP on the fly flush xml to zipfile and push download,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52744350/