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 相关文章推荐
PHP文件上传实例详解!!!
Jan 02 PHP
Discuz 模板语句分析及知识技巧
Aug 21 PHP
php trim 去除空字符的定义与语法介绍
May 31 PHP
php生成N个不重复的随机数实例
Nov 12 PHP
使用PHP备份MYSQL数据的多种方法
Jan 15 PHP
php将数组转换成csv格式文件输出的方法
Mar 14 PHP
PHP限制HTML内容中图片必须是本站的方法
Jun 16 PHP
php实现zip文件解压操作
Nov 03 PHP
AES加解密在php接口请求过程中的应用示例
Oct 26 PHP
PHP调用其他文件中的类
Apr 02 PHP
php 截取中英文混合字符串的方法
May 31 PHP
PHP中echo与print区别点整理
Mar 09 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
二十行语句实现从Excel到mysql的转化
2006/10/09 PHP
yii框架通过控制台命令创建定时任务示例
2014/04/30 PHP
PHPExcel导出2003和2007的excel文档功能示例
2017/01/04 PHP
jQuery基本选择器选择元素使用介绍
2013/04/18 Javascript
js获取当前路径的简单示例代码
2014/01/08 Javascript
jQuery中[attribute!=value]选择器用法实例
2014/12/31 Javascript
基于JavaScript代码实现随机漂浮图片广告
2016/01/05 Javascript
JS中创建函数的三种方式及区别
2016/03/13 Javascript
Js+Ajax,Get和Post在使用上的区别小结
2016/06/08 Javascript
移动端滑动插件Swipe教程
2016/10/16 Javascript
angularjs ocLazyLoad分步加载js文件实例
2017/01/17 Javascript
基于vue组件实现猜数字游戏
2020/05/28 Javascript
JS中获取 DOM 元素的绝对位置实例详解
2018/04/23 Javascript
详解JavaScript 中的批处理和缓存
2020/11/19 Javascript
[04:52]DOTA2亚洲邀请赛附加赛 TOP10精彩集锦
2015/01/29 DOTA
[48:05]2018DOTA2亚洲邀请赛 3.31 小组赛 B组 VGJ.T vs VP
2018/03/31 DOTA
21行Python代码实现拼写检查器
2016/01/25 Python
Python 爬虫学习笔记之多线程爬虫
2016/09/21 Python
用 Python 爬了爬自己的微信朋友(实例讲解)
2017/08/25 Python
在unittest中使用 logging 模块记录测试数据的方法
2018/11/30 Python
python 与服务器的共享文件夹交互方法
2018/12/27 Python
Python字符串逆序的实现方法【一题多解】
2019/02/18 Python
python实现WebSocket服务端过程解析
2019/10/18 Python
Python函数默认参数常见问题及解决方案
2020/03/26 Python
使用卷积神经网络(CNN)做人脸识别的示例代码
2020/03/27 Python
Django admin管理工具TabularInline类用法详解
2020/05/14 Python
JAVA SWT事件四种写法实例解析
2020/06/05 Python
Pytorch 高效使用GPU的操作
2020/06/27 Python
Python爬虫之Selenium设置元素等待的方法
2020/12/04 Python
Python学习之time模块的基本使用
2021/01/17 Python
TOWER London官网:鞋子、靴子、运动鞋等
2019/07/14 全球购物
艺术专业大学生自我评价
2013/09/22 职场文书
车贷收入证明范本
2014/01/09 职场文书
先进个人推荐材料
2014/12/29 职场文书
员工年终考核评语
2014/12/31 职场文书
Python爬虫基础之爬虫的分类知识总结
2021/05/13 Python