如何解决PHP手册GZip编码
| 我正在用Page Speed测试我的网站,结果大约是70/100。启用压缩是降低速度的第一个也是最重要的因素。 我知道我可以通过修改PHP.ini来自动执行此操作,但是我对手动方法(gzencode
)更加感兴趣。
问题是所有浏览器都无法打开网站(Firefox:\“您尝试查看的页面无法显示,因为它使用了无效或不受支持的压缩形式。\”,Chrome:\“ 303,ERR内容编码\ ”等),否则它们会显示编码后的字符串。
实时标题显示浏览器接受编码,并且响应已设置了内容类型,但仍然失败。
GET / HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate
HTTP/1.1 200 OK
content-encoding: gzip
Content-Length: 5827
vary: Accept-Encoding
private function _compress($data) {
//return trim(preg_replace(array(\'/\\>[^\\S ]+/s\',\'/[^\\S ]+\\</s\',\'/(\\s)+/s\'),array(\'>\',\'<\',\'\\\\1\'),$data));
$supportsGzip = strpos($_SERVER[\'HTTP_ACCEPT_ENCODING\'],\'gzip\') !== false;
ob_start();
if ($supportsGzip) {
echo gzencode(trim(preg_replace(\'/\\s+/\',\' \',$data)),9);
} else {
echo $data;
}
$content = ob_get_contents();
header(\"content-type: text/html; charset: UTF-8\");
header(\"cache-control: must-revalidate\");
$offset = 60 * 60;
$expire = \"expires: \" . gmdate(\"D,d M Y H:i:s\",time() + $offset) . \" GMT\";
header($expire);
header(\'Content-Length: \' . strlen($content));
header(\'vary: Accept-Encoding\');
ob_end_clean();
echo $content;
}
如果将content-encoding更改为zlib,则会得到编码后的字符串:
‹������ÕZÿsÛ¶ÿW^‘¥²o‘¨/–-Ë–Ú؉_Ôµ•õÚ_v I°I‚!A©j–Öºnçÿb·»%ÍÚë²nëå?‘þ›=€¤L)’,ÛIw>ŸEâxïáƒ÷°ùÞ½O¶Ÿï߇Žtlؼµ·» $kŸ•¶ ã^ã<܃•\\¾� Ÿº—\\¸Ô6ŒûŽ”^Õ0z½^®WÊ ¿m4ÅjÅ°…XÎ’©Ã¦ænS·]#ÌÕ|8LRPL²ìIÈ»5²-\\É\\™mô=FÀŒJ5\"Ù—RóÝ�³Cý€ÉZ([ÙŠb%¹´YýÑãáîcx}±iD´˜¿KV#4”á§x>¬°à®íÒ ãpÅËæî1øÌ®‘@öm
我真的不太在乎获得压缩,因为我想知道为什么压缩不起作用。
干杯,
解决方法
好吧,我认为这是因为您正在尝试压缩一个空字符串。
我按照您的要求接受了脚本,并在FF和IE中运行了该脚本。
两者均失败,FF表示存在问题(如您所述)。
但是,然后我注意到$ data是一个空字符串。
当我在文件顶部设置
$data = \"Some test data.\";
时,它立即起作用(浏览器显示\“一些测试数据。\”),并检入Firebug,可以看到正确的标题。
Content-Encoding gzip
Content-Length 68
Vary Accept-Encoding
Content-Type text/html
编辑:另外,要指出的是,您的if ($supportsGzip) {
有点奇怪,因为您的else条件实际上应该回显$data
,而不是$content
。
编辑:好的,根据您上面修改的功能,有两个关键问题。
主要问题与以下事实有关:您通过调用ѭ9来清除标题。对PHP Docs的评论指出\“ ob_end_clean()确实会丢弃标头\”。
这意味着您在呼叫ob_end_clean()
之前设置的所有标题都将被擦除。另外,您修改后的函数也不会发送gzip编码标头。
我必须说,这里也可能甚至不需要使用ob_start和相关函数。请尝试以下操作:
function _compress( $data ) {
$supportsGzip = strpos( $_SERVER[\'HTTP_ACCEPT_ENCODING\'],\'gzip\' ) !== false;
if ( $supportsGzip ) {
$content = gzencode( trim( preg_replace( \'/\\s+/\',\' \',$data ) ),9);
header(\'Content-Encoding: gzip\');
} else {
$content = $data;
}
$offset = 60 * 60;
$expire = \"expires: \" . gmdate(\"D,d M Y H:i:s\",time() + $offset) . \" GMT\";
header(\"content-type: text/html; charset: UTF-8\");
header(\"cache-control: must-revalidate\");
header( $expire );
header( \'Content-Length: \' . strlen( $content ) );
header(\'Vary: Accept-Encoding\');
echo $content;
}
_compress( \"Some test data\" );
这在IE和FF中有效,但是我没有时间测试其他浏览器。
如果确实必须使用ob_start和相关函数,请确保在调用ѭ9之后设置标题。
,我建议使用http://php.net/manual/de/function.ob-gzhandler.php,这对我来说是开箱即用的:
在我的index.php中,我只是将其放在一些输出之前:
/**
* Enable GZIP-Compression for Browser that support it.
*/
ob_start(\"ob_gzhandler\");
并对其进行编码!
,一些东西:
您可能想要添加另一个标题:
header(\'Content-Encoding:gzip \');
您正在使用ob_end_clean,它将删除所有回显/打印的内容,而不将其发送到浏览器。根据您要执行的操作,您可能需要使用ob_flush。
为了确保输出得到缓冲和处理(如果使用PHP的输出缓冲压缩,则进行压缩),请确保将所有echo / print语句放置在ob_start和ob_flush放置之间。
-然后再试一次:)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。