php gzip压缩输出的实现方法


Posted in PHP onApril 27, 2013

一、gzip介绍

         gzip是GNU zip的缩写,它是一个GNU自由软件的文件压缩程序,也经常用来表示gzip这种文件格式。软件的作者是Jean-loup Gailly和Mark Adler。1992年10月31日第一次公开发布,版本号是0.1,目前的稳定版本是1.2.4。

        Gzip主要用于Unix系统的文件压缩。我们在Linux中经常会用到后缀为.gz的文件,它们就是GZIP格式的。现今已经成为Internet 上使用非常普遍的一种数据压缩格式,或者说一种文件格式。 当应用Gzip压缩到一个纯文本文件时,效果是非常明显的,经过GZIP压缩后页面大小可以变为原来的40%甚至更小,这取决于文件中的内容。

HTTP协议上的GZIP编码是一种用来改进WEB应用程序性能的技术。web开发中可以通过gzip压缩页面来降低网站的流量,而gzip并不会对cpu造成大量的占用,略微上升,也是几个百分点而已,但是对于页面却能压缩30%以上,非常划算。

      利用Apache中的Gzip模块,我们可以使用Gzip压缩算法来对Apache服务器发布的网页内容进行压缩后再传输到客户端浏览器。这样经过压缩后实际上降低了网络传输的字节数(节约传输的网络I/o),最明显的好处就是可以加快网页加载的速度。

      网页加载速度加快的好处不言而喻,除了节省流量,改善用户的浏览体验外,另一个潜在的好处是Gzip与搜索引擎的抓取工具有着更好的关系。例如 Google就可以通过直接读取gzip文件来比普通手工抓取更快地检索网页。在Google网站管理员工具(Google Webmaster Tools)中你可以看到,sitemap.xml.gz 是直接作为Sitemap被提交的。

      而这些好处并不仅仅限于静态内容,PHP动态页面和其他动态生成的内容均可以通过使用Apache压缩模块压缩,加上其他的性能调整机制和相应的服务器端缓存规则,这可以大大提高网站的性能。因此,对于部署在Linux服务器上的PHP程序,在服务器支持的情况下,我们建议你开启使用Gzip Web压缩。

二、Web服务器处理HTTP压缩的过程如下:

    1. Web服务器接收到浏览器的HTTP请求后,检查浏览器是否支持HTTP压缩(Accept-Encoding 信息);

    2. 如果浏览器支持HTTP压缩,Web服务器检查请求文件的后缀名;

    3. 如果请求文件是HTML、CSS等静态文件,Web服务器到压缩缓冲目录中检查是否已经存在请求文件的最新压缩文件;

    4. 如果请求文件的压缩文件不存在,Web服务器向浏览器返回未压缩的请求文件,并在压缩缓冲目录中存放请求文件的压缩文件;

    5. 如果请求文件的最新压缩文件已经存在,则直接返回请求文件的压缩文件;

    6. 如果请求文件是动态文件,Web服务器动态压缩内容并返回浏览器,压缩内容不存放到压缩缓存目录中。

下面是两个演示图:

                                       未使用Gzip:


                                      php gzip压缩输出的实现方法

                                  开启使用Gzip后:

                                 php gzip压缩输出的实现方法

三、启用apache的gzip功能

      Apache上利用Gzip压缩算法进行压缩的模块有两种:mod_gzip 和mod_deflate。要使用Gzip Web压缩,请首先确定你的服务器开启了对这两个组件之一的支持。

      虽然使用Gzip同时也需要客户端浏览器的支持,不过不用担心,目前大部分浏览器都已经支持Gzip了,如IE、Mozilla Firefox、Opera、Chrome等。

     通过查看HTTP头,我们可以快速判断使用的客户端浏览器是否支持接受gzip压缩。若发送的HTTP头中出现以下信息,则表明你的浏览器支持接受相应的gzip压缩:

Accept-Encoding: gzip 支持mod_gzip  
Accept-Encoding: deflate 支持mod_deflate   Accept-Encoding: gzip,deflate 同时支持mod_gzip 和mod_deflate

如firebug查看:

php gzip压缩输出的实现方法

Accept-Encoding: gzip,deflate 是同时支持mod_gzip 和mod_deflate

   如果服务器开启了对Gzip组件的支持,那么我们就可以在http.conf或.htaccess里面进行定制,下面是一个.htaccess配置的简单实例:

mod_gzip 的配置:

    # mod_gzip:  
    <ifModule mod_gzip.c>  
    mod_gzip_on Yes  
    mod_gzip_dechunk Yes  
    mod_gzip_item_include file \.(html?|txt|css|js|php|pl)$  
    mod_gzip_item_include handler ^cgi-script$  
    mod_gzip_item_include mime ^text/.*  
    mod_gzip_item_include mime ^application/x-javascript.*  
    mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*  
    <ifModule> 

mod_deflate的配置实例:

打开打开apache 配置文件httpd.conf 

将#LoadModule deflate_module modules/mod_deflate.so去除开头的#号

    # mod_deflate:  
    <ifmodule mod_deflate.c>  
    DeflateCompressionLevel 6 #压缩率, 6是建议值.  
    AddOutputFilterByType DEFLATE text/plain  
    AddOutputFilterByType DEFLATE text/html  
    AddOutputFilterByType DEFLATE text/xml  
    AddOutputFilterByType DEFLATE text/css  
    AddOutputFilterByType DEFLATE text/javascript  
    AddOutputFilterByType DEFLATE application/xhtml+xml  
    AddOutputFilterByType DEFLATE application/xml  
    AddOutputFilterByType DEFLATE application/rss+xml  
    AddOutputFilterByType DEFLATE application/atom_xml  
    AddOutputFilterByType DEFLATE application/x-javascript  
    AddOutputFilterByType DEFLATE application/x-httpd-php  
    AddOutputFilterByType DEFLATE image/svg+xml  
    </ifmodule> 

里面的文件MIME类型可以根据自己情况添加,至于PDF 、图片、音乐文档之类的这些本身都已经高度压缩格式,重复压缩的作用不大,反而可能会因为增加CPU的处理时间及浏览器的渲染问题而降低性能。所以就没必要再通过Gzip压缩。通过以上设置后再查看返回的HTTP头,出现以下信息则表明返回的数据已经过压缩。即网站程序所配置的Gzip压缩已生效。

Content-Encoding: gzip

firebug查看:

php gzip压缩输出的实现方法

注意:

1)不管使用mod_gzip 还是mod_deflate,此处返回的信息都一样。因为它们都是实现的gzip压缩方式。

2)CompressionLevel 9是指压缩程度的等级(设置压缩比率),取值范围在从1到9,9是最高等级。据了解,这样做最高可以减少8成大小的传输量(看档案内容而定),最少也能够节省一半。 CompressionLevel 预设可以采用 6 这个数值,以维持耗用处理器效能与网页压缩质量的平衡. 不建议设置太高,如果设置很高,虽然有很高的压缩率,但是占用更多的CPU资源.
3) 对已经是压缩过的图片格式如jpg,音乐档案如mp3、压缩文件如zip之类的,就没必要再压缩了。

四、mod_gzip 和mod_deflate的主要区别是什么?使用哪个更好呢?

       第一个区别是安装它们的Apache Web服务器版本的差异

       Apache 1.x系列没有内建网页压缩技术,所以才去用额外的第三方mod_gzip 模块来执行压缩。而Apache 2.x官方在开发的时候,就把网页压缩考虑进去,内建了mod_deflate 这个模块,用以取代mod_gzip。虽然两者都是使用的Gzip压缩算法,它们的运作原理是类似的。

       第二个区别是压缩质量

       mod_deflate 压缩速度略快而mod_gzip 的压缩比略高。一般默认情况下,mod_gzip 会比mod_deflate 多出4%~6%的压缩量。

       那么,为什么使用mod_deflate?

       第三个区别是对服务器资源的占用

       一般来说mod_gzip 对服务器CPU的占用要高一些。mod_deflate 是专门为确保服务器的性能而使用的一个压缩模块,mod_deflate 需要较少的资源来压缩文件。这意味着在高流量的服务器,使用mod_deflate 可能会比mod_gzip 加载速度更快。

      不太明白?简而言之,如果你的网站,每天不到1000独立访客,想要加快网页的加载速度,就使用mod_gzip。虽然会额外耗费一些服务器资源, 但也是值得的。如果你的网站每天超过1000独立访客,并且使用的是共享的虚拟主机,所分配系统资源有限的话,使用mod_deflate 将会是更好的选择。

     另外,从Apache 2.0.45开始,mod_deflate 可使用DeflateCompressionLevel 指令来设置压缩级别。该指令的值可为1(压缩速度最快,最低的压缩质量)至9(最慢的压缩速度,压缩率最高)之间的整数,其默认值为6(压缩速度和压缩质 量较为平衡的值)。这个简单的变化更是使得mod_deflate 可以轻松媲美mod_gzip 的压缩。

P.S. 对于没有启用以上两种Gzip模块的虚拟空间,还可以退而求其次使用php的zlib函数库(同样需要查看服务器是否支持)来压缩文件,只是这种方法使用起来比较麻烦,而且一般会比较耗费服务器资源,请根据情况慎重使用。

五、zlib.output_compression和ob_gzhandler编码方式压缩

      服务器不支持mod_gzip、mod_deflate模块,若想通过GZIP压缩网页内容,可以考虑两种方式,开启zlib.output_compression或者通过ob_gzhandler编码的方式

      1)zlib.output_compression是在对网页内容压缩的同时发送数据至客户端。

       2)ob_gzhandler是等待网页内容压缩完毕后才进行发送,相比之下前者效率更高,但需要注意的是,两者不能同时使用,只能选其一,否则将出现错误。

       两者的实现方式做简单描述:

    1. zlib.output_compression实现方式

       在默认情况下,zlib.output_compression是关闭:

    ; Transparent output compression using the zlib library  
    ; Valid values for this option are 'off', 'on', or a specific buffer size  
    ; to be used for compression (default is 4KB)  
    ; Note: Resulting chunk size may vary due to nature of compression. PHP  
    ;   outputs chunks that are few hundreds bytes each as a result of  
    ;   compression. If you prefer a larger chunk size for better  
    ;   performance, enable output_buffering in addition.  
    ; Note: You need to use zlib.output_handler instead of the standard  
    ;   output_handler, or otherwise the output will be corrupted.  
    ; http://php.net/zlib.output-compression  
    zlib.output_compression = Off      ; http://php.net/zlib.output-compression-level  
    ;zlib.output_compression_level = -1 

        如需开启需编辑php.ini文件,加入以下内容:
    zlib.output_compression = On  
    zlib.output_compression_level = 6 

       可以通过phpinfo()函数检测结果。

        当zlib.output_compression的Local Value和MasterValue的值同为On时,表示已经生效,这时候访问的PHP页面(包括伪静态页面)已经GZIP压缩了,通过Firebug或者在线网页GZIP压缩检测工具可检测到压缩的效果。
2. ob_gzhandler的实现方式

如果需要使用ob_gzhandler,则需关闭zlib.output_compression,把php.ini文件内容更改为:
    zlib.output_compression = Off 
    zlib.output_compression_level = -1 
通过在PHP文件中插入相关代码实现GZIP压缩P压缩:

    if (extension_loaded('zlib')) {  
        if (  !headers_sent() AND isset($_SERVER['HTTP_ACCEPT_ENCODING']) &&  
              strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)  
        //页面没有输出且浏览器可以接受GZIP的页面  
        {  
            ob_start('ob_gzhandler');  
        }  
    }  
    //待压缩的内容  
    echo $context;  
    ob_end_flush(); 

       不管是zlib.output_compression还是ob_gzhandler,都仅能对PHP文件进行GZIP压缩,对于HTML、CSS、JS等静态文件只能通过调用PHP的方式实现。

最后想说的是,现在主流的浏览器默认使用的是HTTP1.1协议,基本都支持GZIP压缩,对于IE而言,假如你没有选中其菜单栏工具-》Internet 选项-》高级-》HTTP 1.1 设置-》使用 HTTP 1.1,那么,你将感受不到网页压缩后的速度提升所带来的快感!

PHP 相关文章推荐
php5数字型字符串加解密代码
Apr 24 PHP
PHP中函数内引用全局变量的方法
Oct 20 PHP
解析Ubuntu下crontab命令的用法
Jun 24 PHP
php多层数组与对象的转换实例代码
Aug 05 PHP
php函数与传递参数实例分析
Nov 15 PHP
PHP生成唯一订单号的方法汇总
Apr 16 PHP
PHP操作MySQL的mysql_fetch_* 函数的常见用法教程
Dec 25 PHP
php数组函数array_walk用法示例
May 26 PHP
Yii2.0实现生成二维码功能实例
Oct 24 PHP
PHP实现通过strace定位故障原因的方法
Apr 29 PHP
php进行md5加密简单实例方法
Sep 19 PHP
基于laravel-admin 后台 列表标签背景的使用方法
Oct 03 PHP
PHP字符串的编码问题的详细介绍
Apr 27 #PHP
php正则表达式使用的详细介绍
Apr 27 #PHP
基于PHP编程注意事项的小结
Apr 27 #PHP
php二维数组排序与默认自然排序的方法介绍
Apr 27 #PHP
使用Apache的htaccess防止图片被盗链的解决方法
Apr 27 #PHP
php 模拟get_headers函数的代码示例
Apr 27 #PHP
php获取本地图片文件并生成xml文件输出具体思路
Apr 27 #PHP
You might like
几种显示数据的方法的比较
2006/10/09 PHP
分享一下贝贝成长进度的php代码
2012/09/14 PHP
360通用php防护代码(使用操作详解)
2013/06/18 PHP
php利用curl抓取新浪微博内容示例
2014/04/27 PHP
Laravel重写用户登录简单示例
2016/10/08 PHP
跨浏览器的 mouseenter mouseleave 以及 compareDocumentPosition的使用说明
2010/05/04 Javascript
javascript小组件 原生table排序表格脚本(兼容ie firefox opera chrome)
2012/07/25 Javascript
jquery对单选框,多选框,文本框等常见操作小结
2014/01/08 Javascript
javascript的函数作用域
2014/11/12 Javascript
angularJS提交表单(form)
2015/02/09 Javascript
jquery自动补齐功能插件flexselect用法示例
2016/08/06 Javascript
js记录点击某个按钮的次数-刷新次数为初始状态的实例
2017/02/15 Javascript
详谈js中数组(array)和对象(object)的区别
2017/02/27 Javascript
Node.js常用工具之util模块
2017/03/09 Javascript
详解vue事件对象、冒泡、阻止默认行为
2017/03/20 Javascript
vue.js项目打包上线的图文教程
2017/11/16 Javascript
使用Vue-cli 3.0搭建Vue项目的方法
2018/06/07 Javascript
vue 公共列表选择组件,引用Vant-UI的样式方式
2020/11/02 Javascript
[02:26]2016国际邀请赛8月3日开战 中国军团出征西雅图
2016/08/02 DOTA
在Python中实现贪婪排名算法的教程
2015/04/17 Python
python实现定时自动备份文件到其他主机的实例代码
2018/02/23 Python
使用NumPy和pandas对CSV文件进行写操作的实例
2018/06/14 Python
使用python opencv对目录下图片进行去重的方法
2019/01/12 Python
解决pycharm的Python console不能调试当前程序的问题
2019/01/20 Python
python使用time、datetime返回工作日列表实例代码
2019/05/09 Python
选择Python写网络爬虫的优势和理由
2019/07/07 Python
Python如何使用27行代码绘制星星图
2020/07/20 Python
Omio波兰:全欧洲低价大巴、火车和航班搜索和比价
2018/02/16 全球购物
丝芙兰意大利官方网站:Sephora.it
2019/12/13 全球购物
小学班干部竞选演讲稿
2014/04/24 职场文书
电子信息专业应届生自荐信
2014/06/04 职场文书
超市创业计划书
2014/09/15 职场文书
三严三实对照检查材料思想汇报
2014/09/28 职场文书
八年级作文之友情
2019/11/25 职场文书
Oracle 触发器trigger使用案例
2022/02/24 Oracle
Python可视化学习之seaborn绘制矩阵图详解
2022/02/24 Python