PHP 中使用 Zlib 扩展实现页面 GZIP 压缩输出 - 文章教程

PHP 中使用 Zlib 扩展实现页面 GZIP 压缩输出

发布于 2017-11-30 字数 4002 浏览 2056 评论 0

网页压缩是一项由 WEB 服务器和浏览器之间共同遵守的协议,也就是说 WEB 服务器和浏览器都必须支持该技术,所幸的是现在流行的浏览器都是支持的,包括 IE、FireFox、Opera 等浏览器,服务器有 Apache、IIS 和 Nginx 等。双方的协商过程如下:

  1. 首先浏览器请求某个 URL 地址,并在请求的头 header 中设置属性 accept-encoding 值为 gzip, deflate,表明浏览器支持 gzipdeflate 这两种压缩方式,事实上 deflate 也是使用 gzip 压缩协议,下面我们会介绍二者之间的区别。
  2. WEB 服务器接收到请求后判断浏览器是否支持压缩,如果支持就传送压缩后的响应内容,否则传送不经过压缩的内容。
  3. 浏览器获取响应内容后,判断内容是否被压缩,如果是则解压缩,然后显示响应页面的内容。

在实际的应用中我们发现压缩的比率往往在 3 到 10 倍,也就是本来 50k 大小的页面,采用压缩后实际传输的内容大小只有 5k15k 大小,这可以大大节省服务器的网络带宽,同时如果应用程序的响应足够快时,网站的速度瓶颈就转到了网络的传输速度上,因此内容压缩后就可以大大的提升页面的浏览速度。

PHP 中使用 Zlib 扩展实现页面 GZIP 压缩输出

GZIP(GNU-ZIP)是一种压缩技术。经过 GZIP 压缩后页面大小可以变为原来的 30% 甚至更小。这样用户浏览的时候就会感觉很爽很愉快!

要压缩一个页面,首先要获得要输出的内容。PHP 中的 ob_start()ob => output buffer)函数可以实现这个功能,它可以把程序里准备输出的内容先放到一个叫做缓冲区的地方。这个函数一定要在页面输出之前使用,所以一般把它放在代码的最顶端。用 ob_start() 得到要压缩的页面之后,我们就可以压缩页面了,不过好像还缺少一个压缩函数:

// $content 就是要压缩的页面内容
function ob_gzip($content){
    // 如果页面头部信息还没有输出
    if( !headers_sent() &&
    // 而且zlib扩展已经加载到PHP中
    extension_loaded("zlib") &&
    //而且浏览器说它可以接受GZIP的页面
    strstr($_SERVER["HTTP_ACCEPT_ENCODING"],"gzip")){
        $content = gzencode($content." //此页已压缩",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();

结束缓冲区并输出内容。当然不用这个函数也行,因为程序执行到最后会自动将缓冲区内容输出。

最后完整的示例如下:

//启用一个带有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." //此页已压缩",9);
        header("Content-Encoding: gzip");
        header("Vary: Accept-Encoding");
        header("Content-Length: ".strlen($content));
    }
    return $content;
}

经过实际测试,上面代码中如果不用 GZIP,是 4.69KB=4802.56B,启用GZIP后缩小为 104B ,压缩率 97%

如果你对这篇文章有疑问,欢迎到本站 社区 发帖提问或使用手Q扫描下方二维码加群参与讨论,获取更多帮助。

扫码加入群聊

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

目前还没有任何评论,快来抢沙发吧!

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

2891 文章
评论
84935 人气
更多

推荐作者

勿忘心安

文章 0 评论

ekko

文章 0 评论

江挽川

文章 0 评论

献世佛

文章 0 评论

Meets

文章 0 评论