PHP zlib扩展实现页面GZIP压缩输出


Posted in PHP onJune 17, 2010

要实现GZIP压缩页面需要浏览器和服务器共同支持,实际上就是服务器压缩,传到浏览器后浏览器解压并解析。浏览器那边不需要我们担心,因为现在绝大多数浏览器都支持解析GZIP过的页面。我们只要把页面在服务器端压缩再输出到浏览器就行了。

有点罗嗦,下面说正事:

正如要制作压缩饼干,先要拿到原料,要压缩一个页面,首先要获得要输出的内容。PHP中的ob_start()(ob => output buffer)函数可以实现这个功能,它可以把程序里准备输出的内容先放到一个叫做“缓冲区”的地方,当然,你可以理解为制作压缩饼干的暂时放原料的工作台。
这个函数一定要在页面输出之前使用,所以一般把它放在代码的最顶端。因为它就像是一个工作台,所以你要在原料到来之前就要准备好它,否则原料来了没地方放,会出问题的。用ob_start()得到要压缩的页面之后,我们就可以制作压缩饼干了,不对,应该是可以压缩页面了!不过好像还缺少一台压缩机, EZ,我们用PHP带的zlib扩展做一台:

function ob_gzip($content) // $content 就是要压缩的页面内容,或者说饼干原料 
{ 
if( !headers_sent() && // 如果页面头部信息还没有输出 
extension_loaded("zlib") && // 而且zlib扩展已经加载到PHP中 
strstr($_SERVER["HTTP_ACCEPT_ENCODING"],"gzip")) //而且浏览器说它可以接受GZIP的页面 
{ 
$content = gzencode($content." \n//此页已压缩",9); 为准备压缩的内容贴上“//此页已压缩”的注释标签,然后用zlib提供的gzencode()函数执行级别为9的压缩,这个参数值范围是0-9,0表示无压缩,9表示最大压缩,当然压缩程度越高越费CPU。 //然后用header()函数给浏览器发送一些头部信息,告诉浏览器这个页面已经用GZIP压缩过了! 
header("Content-Encoding: gzip"); 
header("Vary: Accept-Encoding"); 
header("Content-Length: ".strlen($content)); 
} 
return $content; //返回压缩的内容,或者说把压缩好的饼干送回工作台。 
}

压缩机做好了之后,我们把压缩机放到工作台上,于是原来的ob_start()变成

ob_start('ob_gzip'); //没错,就是给ob_start()加一个参数,参数名就是我们刚才做的“压缩机”的函数名。这样当内容进入缓冲区后PHP就会调用ob_gzip函数把它压缩了。
好了,所有的工作已完成,最后交货:

ob_end_flush(); //结束缓冲区,输出内容。当然,不用这个函数也行,因为程序执行到最后会自动将缓冲区内容输出。
完整的示例如下:

<?php 
//启用一个带有ob_gzip压缩机的工作台 
ob_start('ob_gzip'); 
//准备一些待压缩的内容 
for($i=0; $i<100; $i++) 
{ 
echo('这里是压缩饼干的原料,这里是压缩饼干的原料,原料'); 
} 
//输出压缩成果 
ob_end_flush(); 
//这是ob_gzip压缩机 
function ob_gzip($content) 
{ 
if( !headers_sent() && 
extension_loaded("zlib") && 
strstr($_SERVER["HTTP_ACCEPT_ENCODING"],"gzip")) 
{ 
$content = gzencode($content." \n//此页已压缩",9); header("Content-Encoding: gzip"); 
header("Vary: Accept-Encoding"); 
header("Content-Length: ".strlen($content)); 
} 
return $content; 
} 
?>

经过实际测试,上面代码中如果不用GZIP,是4.69KB=4802.56B,启用GZIP后缩小为104B ,呃……我数学可能不好,自己算下压缩到了原来的百分之多少吧。。

另外,下面是用FlashGet获取的日志信息,可以看到我们程序里加的header信息:

Fri Jan 25 17:53:10 2008 HTTP/1.1 200 OK 
Fri Jan 25 17:53:10 2008 Server: Microsoft-IIS/5.1 
Fri Jan 25 17:53:10 2008 Date: Fri, 25 Jan 2008 09:53:10 GMT 
Fri Jan 25 17:53:10 2008 Connection: close 
Fri Jan 25 17:53:10 2008 X-Powered-By: PHP/5.2.5 
Fri Jan 25 17:53:10 2008 Content-Encoding: gzip 
Fri Jan 25 17:53:10 2008 Vary: Accept-Encoding 
Fri Jan 25 17:53:10 2008 Content-Length: 104 
Fri Jan 25 17:53:10 2008 Content-type: text/html
PHP 相关文章推荐
php下载远程文件类(支持断点续传)
Nov 14 PHP
批量修改RAR文件注释的php代码
Nov 20 PHP
调整PHP的性能
Oct 30 PHP
关于js和php对url编码的处理方法
Mar 04 PHP
深入理解PHP内核(一)
Nov 10 PHP
总结PHP代码规范、流程规范、git规范
Jun 18 PHP
tp5(thinkPHP5)框架连接数据库的方法示例
Dec 24 PHP
PHP使用mongoclient简单操作mongodb数据库示例
Feb 08 PHP
php常用字符串查找函数strstr()与strpos()实例分析
Jun 21 PHP
php创建多级目录与级联删除文件的方法示例
Sep 12 PHP
PHP高并发和大流量解决方案整理
Dec 24 PHP
ThinkPHP 5 AJAX跨域请求头设置实现过程解析
Oct 28 PHP
PHP,ASP.JAVA,JAVA代码格式化工具整理
Jun 15 #PHP
PHP迅雷、快车、旋风下载专用链转换代码
Jun 15 #PHP
PHP中实现汉字转区位码应用源码实例解析
Jun 14 #PHP
joomla内置的表单验证功能使用方法
Jun 11 #PHP
实战mysql导出中文乱码及phpmyadmin导入中文乱码的解决方法
Jun 11 #PHP
Php获取金书网的书名的实现代码
Jun 11 #PHP
PHP中json_encode、json_decode与serialize、unserialize的性能测试分析
Jun 09 #PHP
You might like
全国FM电台频率大全 - 10 江苏省
2020/03/11 无线电
php中mysql模块部分功能的简单封装
2011/09/30 PHP
PHP数据集构建JSON格式及新数组的方法
2012/11/07 PHP
php基础教程
2015/08/26 PHP
Thinkphp极验滑动验证码实现步骤解析
2020/11/24 PHP
jQuery循环滚动展示代码 可应用到文字和图片上
2012/05/11 Javascript
Jquery index()方法 获取相应元素索引值
2012/10/12 Javascript
jquery实现滑动图片自己测试的例子
2013/11/05 Javascript
使用js检测浏览器是否支持html5中的video标签的方法
2014/03/12 Javascript
JS数组的遍历方式for循环与for...in
2014/07/31 Javascript
网站基于flash实现的Banner图切换效果代码
2014/10/14 Javascript
jQuery获得包含margin的outerWidth和outerHeight的方法
2015/03/25 Javascript
js 点击a标签 获取a的自定义属性方法
2016/11/21 Javascript
概述如何实现一个简单的浏览器端js模块加载器
2016/12/07 Javascript
JQuery页面随滚动条动态加载效果的简单实现(推荐)
2017/02/08 Javascript
详解Angularjs 如何自定义Img的ng-load 事件
2017/02/15 Javascript
浅谈Vue响应式(数组变异方法)
2018/05/07 Javascript
vue实现微信二次分享以及自定义分享的示例
2019/03/20 Javascript
使用 vue 实例更好的监听事件及vue实例的方法
2019/04/22 Javascript
JavaScript通如何过RGraph实现动态仪表盘
2020/10/15 Javascript
Vue检测屏幕变化来改变不同的charts样式实例
2020/10/26 Javascript
使用Python进行新浪微博的mid和url互相转换实例(10进制和62进制互算)
2014/04/25 Python
python输出当前目录下index.html文件路径的方法
2015/04/28 Python
Python中使用遍历在列表中添加字典遇到的坑
2019/02/27 Python
Python简单I/O操作示例
2019/03/18 Python
Python如何爬取微信公众号文章和评论(基于 Fiddler 抓包分析)
2019/06/28 Python
python使用numpy实现直方图反向投影示例
2020/01/17 Python
python opencv 检测移动物体并截图保存实例
2020/03/10 Python
美国南部最大的家族百货公司:Belk
2017/01/30 全球购物
杭州龙健科技笔试题.net部分笔试题
2016/01/24 面试题
单位创先争优活动方案
2014/01/26 职场文书
2014年最新学习全国两会精神心得
2014/03/17 职场文书
保安公司服务承诺书
2014/05/28 职场文书
建筑安全责任书范本
2014/07/24 职场文书
民族学专业职业生涯规划范文:积跬步以至千里
2014/09/11 职场文书
浅谈Python中的正则表达式
2021/06/28 Python