PHP中的gzcompress、gzdeflate、gzencode函数详解


Posted in PHP onJuly 29, 2014

PHP中存在一组看起来很像的压缩解压函数:

压缩函数:gzcompress gzdeflate gzencode

解压函数:gzuncompress gzinflate gzdecode

gzdecode是PHP 5.4.0之后才加入的,使用的时候要注意兼容性问题。

这几个函数都以gz开头,让人想到gzip压缩,而光看函数名却又看不出它们之间的区别,只能查文档。

gzcompress gzdeflate gzencode函数的区别在于它们压缩的数据格式不同:

gzcompress使用的是ZLIB格式;

gzdeflate使用的是纯粹的DEFLATE格式;

gzencode使用的是GZIP格式;

但是有一点是相同的,它们压缩数据时都使用了DEFLATE压缩算法(理论上ZLIB和GZIP格式可以使用其他的压缩算法,但是目前实践中只使用DEFLATE算法),ZLIB和GZIP只不过是在DEFLATE的基础之上加了一些头部和尾部而已。

顺便提一下,HTTP协议中的Content-Encoding: deflate使用的是ZLIB格式而不是纯DEFLATE格式。

从PHP 5.4.0开始,gzcompress和gzdeflate函数加入了第三个参数$encoding,可以是三个常量:

ZLIB_ENCODING_RAW 对应于纯DEFLATE格式;

ZLIB_ENCODING_GZIP 对应于GZIP格式;

ZLIB_ENCODING_DEFLATE 对应于ZLIB格式(注意不是纯DEFLATE格式);

虽然文档没有提及,但是这三个常量也可以用在gzencode函数的第三个参数$encoding_mode中。

其实从PHP 5.4.0开始,这三个函数是一样的,只不过第三个参数的默认值不同;如果调用时传入第三个参数,那么这三个函数返回的数据相同。可以写一个简单的脚本测试:

<?php

$url = 'http://3water.com';

$s1 = gzdeflate($url, 1);

$s2 = gzencode($url, 1, ZLIB_ENCODING_RAW);

if (strcmp($s1, $s2) == 0) echo 'the same';

?>

运行可以看到$s1和$s2是相同的,为什么会这样呢?可以从PHP源码中找到答案,打开php-5.5.4\ext\zip\zlib.c,可以找到这样的代码:

#define PHP_ZLIB_ENCODE_FUNC(name, default_encoding) \

static PHP_FUNCTION(name) \

{ \

    char *in_buf, *out_buf; \

    int in_len; \

    size_t out_len; \

    long level = -1; \

    long encoding = default_encoding; \

    if (default_encoding) { \

        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &in_buf, &in_len, &level, &encoding)) { \

            return; \

        } \

    } else { \

        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|l", &in_buf, &in_len, &encoding, &level)) { \

            return; \

        } \

    } \

    if (level < -1 || level > 9) { \

        php_error_docref(NULL TSRMLS_CC, E_WARNING, "compression level (%ld) must be within -1..9", level); \

        RETURN_FALSE; \

    } \

    switch (encoding) { \

        case PHP_ZLIB_ENCODING_RAW: \

        case PHP_ZLIB_ENCODING_GZIP: \

        case PHP_ZLIB_ENCODING_DEFLATE: \

            break; \

        default: \

            php_error_docref(NULL TSRMLS_CC, E_WARNING, "encoding mode must be either ZLIB_ENCODING_RAW, ZLIB_ENCODING_GZIP or ZLIB_ENCODING_DEFLATE"); \

            RETURN_FALSE; \

    } \

    if (SUCCESS != php_zlib_encode(in_buf, in_len, &out_buf, &out_len, encoding, level TSRMLS_CC)) { \

        RETURN_FALSE; \

    } \

    RETURN_STRINGL(out_buf, out_len, 0); \

}


/* NOTE: The naming of these userland functions was quite unlucky */

/* {{{ proto binary gzdeflate(binary data[, int level = -1[, int encoding = ZLIB_ENCODING_RAW])

   Encode data with the raw deflate encoding */

PHP_ZLIB_ENCODE_FUNC(gzdeflate, PHP_ZLIB_ENCODING_RAW);

/* }}} */
/* {{{ proto binary gzencode(binary data[, int level = -1[, int encoding = ZLIB_ENCODING_GZIP])

   Encode data with the gzip encoding */

PHP_ZLIB_ENCODE_FUNC(gzencode, PHP_ZLIB_ENCODING_GZIP);

/* }}} */
/* {{{ proto binary gzcompress(binary data[, int level = -1[, int encoding = ZLIB_ENCODING_DEFLATE])

   Encode data with the zlib encoding */

PHP_ZLIB_ENCODE_FUNC(gzcompress, PHP_ZLIB_ENCODING_DEFLATE);

/* }}} */

可以看到,gzdeflate gzencode gzcompress三个函数都是用相同的PHP_ZLIB_ENCODE_FUNC宏定义的(是不是有些泛型的意味?),所以它们当然是相同的。

代码中的注释也承认这几个函数的名字起得不好,至于为什么会用这样的名字就不得而知了。

PHP 相关文章推荐
php一些公用函数的集合
Mar 27 PHP
snoopy 强大的PHP采集类使用实例代码
Dec 09 PHP
PHP管理依赖(dependency)关系工具 Composer 安装与使用
Aug 18 PHP
使用PHP和HTML5 FormData实现无刷新文件上传教程
Sep 06 PHP
php简单smarty入门程序实例
Jun 11 PHP
Thinkphp结合ajaxFileUpload实现异步图片传输示例
Mar 13 PHP
PHP用continue跳过本次循环中剩余代码的注意点
Jun 27 PHP
php判断str字符串是否是xml格式数据的方法示例
Jul 26 PHP
PHP操作Redis常用技巧总结
Apr 24 PHP
laravel model 两表联查示例
Oct 24 PHP
Yii2框架中一些折磨人的坑
Dec 15 PHP
PHP操作Redis常用命令的实例详解
Dec 23 PHP
VB中的RasEnumConnections函数返回632错误解决方法
Jul 29 #PHP
php中的curl_multi系列函数使用例子
Jul 29 #PHP
PHP使用CURL_MULTI实现多线程采集的例子
Jul 29 #PHP
PHP实现把文本中的URL转换为链接的auolink()函数分享
Jul 29 #PHP
PHP自带函数给数字或字符串自动补齐位数
Jul 29 #PHP
Win2003+apache+PHP+SqlServer2008 配置生产环境
Jul 29 #PHP
php实现读取超大文件的方法
Jul 28 #PHP
You might like
PHP 分页原理分析,大家可以看看
2009/12/21 PHP
php编写的抽奖程序中奖概率算法
2015/05/14 PHP
PHP中error_reporting()用法详解
2015/08/31 PHP
php 实现进制相互转换
2016/04/07 PHP
PHP实现的微信APP支付功能示例【基于TP5框架】
2019/09/16 PHP
不间断滚动JS打包类,基本可以实现所有的滚动效果,太强了
2007/12/08 Javascript
JavaScript实现算术平方根算法-代码超简单
2015/09/11 Javascript
JS实现字符串转日期并比较大小实例分析
2015/12/09 Javascript
Nodejs下用submit提交表单提示cannot post错误的解决方法
2016/11/21 NodeJs
微信小程序-图片、录音、音频播放、音乐播放、视频、文件代码实例
2016/11/22 Javascript
JavaScript自定义分页样式
2017/01/17 Javascript
微信小程序实战之顶部导航栏(选项卡)(1)
2020/06/19 Javascript
vue+swiper实现组件化开发的实例代码
2017/10/26 Javascript
微信小程序ibeacon三点定位详解
2018/10/31 Javascript
node app 打包工具pkg的具体使用
2019/01/17 Javascript
js实现列表向上无限滚动
2020/01/13 Javascript
JS正则表达式常见函数与用法小结
2020/04/13 Javascript
flask中主动抛出异常及统一异常处理代码示例
2018/01/18 Python
pycharm修改界面主题颜色的方法
2019/01/17 Python
python函数的万能参数传参详解
2019/07/26 Python
将python包发布到PyPI和制作whl文件方式
2019/12/25 Python
pytorch实现保证每次运行使用的随机数都相同
2020/02/20 Python
理解Django 中Call Stack机制的小Demo
2020/09/01 Python
python用Configobj模块读取配置文件
2020/09/26 Python
详解Python流程控制语句
2020/10/28 Python
CSS3中动画属性transform、transition和animation属性的区别
2016/09/25 HTML / CSS
日本土著品牌,综合型购物网站:Cecile
2016/08/23 全球购物
欧洲高端品牌直销店:Fashionesta
2016/08/31 全球购物
英国领先的在线高尔夫商店:Scottsdale Golf
2019/08/26 全球购物
Java中各种基本数据类型的默认值都是什么
2016/12/22 面试题
销售演讲稿范文
2014/01/08 职场文书
五四青年节演讲稿
2014/05/26 职场文书
公务员学习习总书记“三严三实”思想汇报
2014/09/19 职场文书
就业推荐表导师评语
2014/12/31 职场文书
汽车销售员岗位职责
2015/04/11 职场文书
工作后的感想
2015/08/07 职场文书