不,它不会返回 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 生成的 CRC 看起来非常奇怪。)
// 这将阻止 Opera 崩溃,gunzip 将正常工作,并且
// 其他浏览器不会无限期地保持加载状态。
//
// 去除旧的 CRC (它在那里,但不会显示
// 全部 -- 非常奇怪)
$contents = substr($contents, 0, strlen($contents) - 4);
// 只显示压缩后的数据
echo $contents;
// 输出 CRC,然后输出原始的大小
gzip_PrintFourChars($Crc);
gzip_PrintFourChars($Size);
// 完成。您可以通过 gzcompressing
// 另一个字符串并重新处理 CRC 和 Size 内容来附加更多数据
// 对于它也是如此。重复直到完成。
function gzip_PrintFourChars($Val)
{
for ($i = 0; $i < 4; $i ++)
{
echo chr($Val % 256);
$Val = floor($Val / 256);
}
}
?>