不,它不会返回 gzip 压缩的数据——具体来说,CRC 会出错。但是,经过大量的修改输出,我得出了一个解决方案。我还对其进行了大量的注释,指出了奇怪的地方。
<?php
// 开始输出缓冲区
ob_start();
ob_implicit_flush(0);
// 在此处输出内容...
// 获取输出缓冲区的内容
$contents = ob_get_contents();
ob_end_clean();
// 告诉浏览器他们将获得 gzip 数据
// 当然,您已经检查了他们是否支持 gzip 或 x-gzip
// 并且如果他们支持 x-gzip,您会将标题更改为
// x-gzip,对吧?
header("Content-Encoding: gzip");
// 显示 gzip 文件的头部
// 感谢 [email protected]!
// 只显示一次
echo "\x1f\x8b\x08\x00\x00\x00\x00\x00";
// 找出原始的大小和 CRC 以备后用
$Size = strlen($contents);
$Crc = crc32($contents);
// 压缩数据
$contents = gzcompress($contents, 9);
// 我们不能在这里输出它,因为 CRC 出错了。
// 如果我尝试在此处“echo $contents”,则会发送压缩
// 数据,但并不完整。最后四个字节是
// CRC。发送了三个。最后一个
// 处于悬而未决的状态。此外,如果我们“echo $contents”,则下一个
// 我们回显的字节将不会发送到客户端。我不确定
// 这是 4.0.2 中的错误还是不是,但避免的最佳方法
// 这是在压缩数据末尾放置正确的 CRC
// 数据。(由 gzcompress 生成的看起来非常错误。)
// 这将阻止 Opera 崩溃,gunzip 将起作用,并且
// 其他浏览器不会无限期地加载。
//
// 去掉旧的 CRC(它在那里,但不会显示
// 完全——非常奇怪)
$contents = substr($contents, 0, strlen($contents) - 4);
// 只显示压缩数据
echo $contents;
// 输出 CRC,然后输出原始的大小
gzip_PrintFourChars($Crc);
gzip_PrintFourChars($Size);
// 完成。您可以通过 gzcompress 追加更多数据
// 另一个字符串并重新修改 CRC 和 Size 内容
// 它也一样。重复直到完成。
function gzip_PrintFourChars($Val)
{
for ($i = 0; $i < 4; $i ++)
{
echo chr($Val % 256);
$Val = floor($Val / 256);
}
}
?>