这是我为在我的网站上压缩内容而编写的脚本,该脚本位于“gzip.php”中。我使用它的方式是在我要启用gzipping的页面上我在顶部和底部包含文件我调用输出函数如下:
print_gzipped_page('javascript')
如果文件是css文件,我使用'css'作为$ type-argument,如果它是一个php文件,我调用该函数而不声明任何参数。该脚本在除Opera之外的所有浏览器中都能正常工作,这会导致错误,因为数据损坏导致无法解码页面。谁能告诉我我做错了什么?
<?php
function print_gzipped_page($type = false) {
if(headers_sent()){
$encoding = false;
}
elseif( strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'x-gzip') !== false ){
$encoding = 'x-gzip';
}
elseif( strpos($_SERVER['HTTP_ACCEPT_ENCODING'],'gzip') !== false ){
$encoding = 'gzip';
}
else{
$encoding = false;
}
if ($type!=false) {
$type_header_array = array("css" => "Content-Type: text/css", "javascript" => "Content-Type: application/x-javascript");
$type_header = $type_header_array[$type];
}
$contents = ob_get_contents();
ob_end_clean();
$etag = '"' . md5($contents) . '"';
$etag_header = 'Etag: ' . $etag;
header($etag_header);
if ($type!=false) {
header($type_header);
}
if (isset($_SERVER['HTTP_IF_NONE_MATCH']) and $_SERVER['HTTP_IF_NONE_MATCH']==$etag) {
header("HTTP/1.1 304 Not Modified");
exit();
}
if($encoding){
header('Content-Encoding: '.$encoding);
print("\x1f\x8b\x08\x00\x00\x00\x00\x00");
$size = strlen($contents);
$contents = gzcompress($contents, 9);
$contents = substr($contents, 0, $size);
}
echo $contents;
exit();
}
ob_start();
ob_implicit_flush(0);
?>
附加信息:如果要压缩的文档长度仅为10-15个字符,则脚本可以使用。
感谢您的帮助,更正版本:
<?php
function print_gzipped_page($type = false) {
if(headers_sent()){
$encoding = false;
}
elseif( strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'x-gzip') !== false ){
$encoding = 'x-gzip';
}
elseif( strpos($_SERVER['HTTP_ACCEPT_ENCODING'],'gzip') !== false ){
$encoding = 'gzip';
}
else{
$encoding = false;
}
if ($type!=false) {
$type_header_array = array("css" => "Content-Type: text/css", "javascript" => "Content-Type: application/x-javascript");
$type_header = $type_header_array[$type];
header($type_header);
}
$contents = ob_get_contents();
ob_end_clean();
$etag = '"' . md5($contents) . '"';
$etag_header = 'Etag: ' . $etag;
header($etag_header);
if (isset($_SERVER['HTTP_IF_NONE_MATCH']) and $_SERVER['HTTP_IF_NONE_MATCH']==$etag) {
header("HTTP/1.1 304 Not Modified");
exit();
}
if($encoding){
header('Content-Encoding: ' . $encoding);
$contents = gzencode($contents, 9);
}
$length = strlen($contents);
header('Content-Length: ' . $length);
echo $contents;
exit();
}
ob_start();
ob_implicit_flush(0);
?>
答案 0 :(得分:3)
这种做法有点过于笨拙。而是使用ob_gzhandler
。它会自动GZIP客户端支持的内容并设置必要的标题。
ob_start('ob_gzhandler');
readfile($path);
答案 1 :(得分:1)
有两件事突出:
1)您似乎没有将Content-Length标头设置为压缩数据的大小。 (也许我忽略了它。)如果你没有设置它,浏览器可能会认为你太早发送数据了。
2)您正在使用未压缩的$ size执行压缩$ content的子记录。当内部结构具有EOF标记时,某些浏览器将停止解压缩,但其他浏览器(Opera?)可能会尝试解压缩整个下载的缓冲区。这肯定会给你一个“损坏的数据”错误。您可能没有看到小缓冲区出现此问题,因为开销量和压缩量可能完全匹配。