不,它不會傳回 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 檔案的標頭
// 感謝 ck@medienkombinat.de!
// 只顯示一次
echo "\x1f\x8b\x08\x00\x00\x00\x00\x00";
// 計算原始檔案的大小和 CRC,以便稍後使用
$Size = strlen($contents);
$Crc = crc32($contents);
// 壓縮資料
$contents = gzcompress($contents, 9);
// 我們不能直接在這裡輸出,因為 CRC 錯亂了。
// 如果我在此時嘗試「echo $contents」,壓縮
// 資料會被傳送,但不完全。末尾有四個位元組
// 是 CRC。傳送了三個。最後一個位元組
// 被留在 limbo 中。此外,如果我們「echo $contents」,則
// 我們 echo 的下一個位元組將不會傳送給用戶端。我不確定
// 這是不是 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);
// 完成。您可以使用 gzcompress 附加更多資料
// 另一個字串,並為它重新計算 CRC 和大小。
// 重複直到完成。
function gzip_PrintFourChars($Val)
{
for ($i = 0; $i < 4; $i ++)
{
echo chr($Val % 256);
$Val = floor($Val / 256);
}
}
?>