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实现文件安全下载
Oct 09 PHP
文件系统基本操作类
Nov 23 PHP
如何使用PHP中的字符串函数
Nov 24 PHP
php中取得URL的根域名的代码
Mar 23 PHP
Views rows style模板重写代码
May 16 PHP
php设计模式之观察者模式的应用详解
May 21 PHP
PHP判断是否有Get参数的方法
May 05 PHP
PHP编程中的常见漏洞和代码实例
Aug 06 PHP
php基于SQLite实现的分页功能示例
Jun 21 PHP
Laravel框架基于ajax实现二级联动功能示例
Jan 17 PHP
php/JS实现的生成随机密码(验证码)功能示例
Jun 06 PHP
php菜单/评论数据递归分级算法的实现方法
Aug 01 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
phpMyAdmin下载、安装和使用入门教程
2007/05/31 PHP
关于PHP模板Smarty的初级使用方法以及心得分享
2013/06/21 PHP
php断点续传之文件分割合并详解
2016/12/13 PHP
Laravel+Intervention实现上传图片功能示例
2019/07/09 PHP
PHP中散列密码的安全性分析
2019/07/26 PHP
Yii框架的路由配置方法分析
2019/09/09 PHP
php和nginx交互实例讲解
2019/09/24 PHP
javascript 24小时弹出一次的代码(利用cookies)
2009/09/03 Javascript
JavaScript中的this关键字介绍与使用实例
2013/06/21 Javascript
jQuery使用slideUp方法实现控制元素缓慢收起
2015/03/27 Javascript
JavaScript获取一个范围内日期的方法
2015/04/24 Javascript
文本框只能输入数字的实现方法(兼容IE火狐)
2016/06/25 Javascript
nodejs require js文件入口,在package.json中指定默认入口main方法
2018/10/10 NodeJs
微信小程序授权登陆及每次检查是否授权实例代码
2019/09/18 Javascript
JS桶排序的简单理解与实现方法示例
2019/11/25 Javascript
js实现AI五子棋人机大战
2020/05/28 Javascript
openlayers实现图标拖动获取坐标
2020/09/25 Javascript
[01:04:05]Mineski vs TNC 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
Python做简单的字符串匹配详解
2017/03/21 Python
python实现栅栏加解密 支持密钥加密
2019/03/20 Python
python字符串下标与切片及使用方法
2020/02/13 Python
Python3+selenium实现cookie免密登录的示例代码
2020/03/18 Python
Django Serializer HiddenField隐藏字段实例
2020/03/31 Python
一篇文章搞懂python的转义字符及用法
2020/09/03 Python
python 爬取腾讯视频评论的实现步骤
2021/02/18 Python
纯CSS3实现漂亮的input输入框动画样式库(Text input love)
2018/12/29 HTML / CSS
Alba Moda瑞士网上商店:独家意大利时尚女装销售
2016/11/28 全球购物
菲律宾旅游网站:Expedia菲律宾
2017/10/11 全球购物
日语专业毕业生自荐信
2013/11/11 职场文书
初中生学习生活的自我评价
2013/11/20 职场文书
幼儿园社区活动总结
2014/07/07 职场文书
消防演习通知
2015/04/25 职场文书
物业保安辞职信
2015/05/12 职场文书
2015年信息化建设工作总结
2015/07/23 职场文书
结婚幸福感言
2015/08/01 职场文书
JavaScript实现简单计时器
2021/06/22 Javascript