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安全配置 如何配置使其更安全
Dec 16 PHP
关于PHP的相似度计算函数:levenshtein的使用介绍
Apr 15 PHP
基于php权限分配的实现代码
Apr 28 PHP
如何使用PHP获取指定日期所在月的开始日期与结束日期
Aug 01 PHP
php检测用户是否用手机(Mobile)访问网站的类
Jan 09 PHP
PHP实现视频文件上传完整实例
Aug 28 PHP
PHP生成随机密码方法汇总
Aug 27 PHP
解决PHP里大量数据循环时内存耗尽的方法
Oct 10 PHP
php自定义函数实现汉字转换utf8编码的方法
Sep 29 PHP
如何打开php的gd2库
Feb 09 PHP
laravel5.6实现数值转换
Oct 23 PHP
YII2 全局异常处理深入讲解
Mar 24 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
浅谈PHP值mysql操作类
2016/06/29 PHP
Laravel学习教程之request validation的编写
2017/10/25 PHP
PHP后台实现微信小程序登录
2018/08/03 PHP
php中目录操作opendir()、readdir()及scandir()用法示例
2019/06/08 PHP
图片之间的切换
2006/06/26 Javascript
javascript得到XML某节点的子节点个数的脚本
2008/10/11 Javascript
JavaScript中的View-Model使用介绍
2011/08/11 Javascript
JS获取DropDownList的value值与text值的示例代码
2014/01/07 Javascript
Javascript 实现图片无缝滚动
2014/12/19 Javascript
JavaScript异步加载浅析
2014/12/28 Javascript
jQuery easyui的validatebox校验规则扩展及easyui校验框validatebox用法
2016/01/18 Javascript
详解JS中的立即执行函数
2017/02/24 Javascript
JavaScript全屏和退出全屏事件总结(附代码)
2017/08/17 Javascript
Js中async/await的执行顺序详解
2017/09/22 Javascript
[56:56]VG vs LGD 2019国际邀请赛淘汰赛 胜者组 BO3 第一场 8.22
2019/09/05 DOTA
python 解析html之BeautifulSoup
2009/07/07 Python
python求素数示例分享
2014/02/16 Python
使用Protocol Buffers的C语言拓展提速Python程序的示例
2015/04/16 Python
Python简单计算数组元素平均值的方法示例
2017/12/26 Python
详解python 拆包可迭代数据如tuple, list
2017/12/29 Python
python基于ID3思想的决策树
2018/01/03 Python
python画一个玫瑰和一个爱心
2020/08/18 Python
python将txt文件读取为字典的示例
2018/12/22 Python
python实现维吉尼亚加密法
2019/03/20 Python
解决pycharm 远程调试 上传 helpers 卡住的问题
2019/06/27 Python
将python字符串转化成长表达式的函数eval实例
2020/05/11 Python
解决echarts中饼图标签重叠的问题
2020/05/16 Python
Python3爬虫中关于中文分词的详解
2020/07/29 Python
python接口自动化框架实战
2020/12/23 Python
python元组拆包实现方法
2021/02/28 Python
美国波西米亚风格服装品牌:Show Me Your Mumu
2018/01/05 全球购物
意外伤害赔偿协议书范文
2014/09/23 职场文书
员工担保书范本
2015/09/22 职场文书
党章党规党纪学习心得体会
2016/01/14 职场文书
PHP对接阿里云虚拟号的实现(号码隐私保护)
2021/04/06 PHP
Python中的协程(Coroutine)操作模块(greenlet、gevent)
2022/05/30 Python