PHP的zlib压缩工具扩展包学习
总算到了我们压缩相关扩展的最后一篇文章了,最后我们要学习的也是 Linux 下非常常用的一种压缩格式:.gz 的压缩扩展。作为 PHP 的自带扩展,就像 zip 一样,zlib 扩展是随着 PHP 的安装包一起发布的,所以我们在编译的时候直接加上 --with-zlib 就可以了,如果无法找到对应的软件包的话,使用 yum 安装相应的软件包即可。
创建压缩包
// 创建压缩包
$zp = gzopen('./gztest.gz', "w9");
gzwrite($zp, "Only test, test, test, test, test, test!\n");
gzclose($zp);
压缩包的创建非常地简单,不过 PHP 的这个扩展中,只能使用 gzwrite() 来创建这种字符串类型的压缩包,无法直接将某些目录或者文件进行打包。
创建压缩包成功后,我们就可以通过系统的 tar 命令来解压或者查看文件了。
读取压缩包内容
// 读取压缩包
$zp = gzopen('./gztest.gz', "r");
echo gzread($zp, 3);
gzpassthru($zp); // 输出 gz 文件指针中的所有剩余数据
// Only test, test, test, test, test, test!
echo PHP_EOL;
gzpassthru($zp);
//
gzrewind($zp); // 将 gz 指针的游标返回到最开始的位置
gzpassthru($zp);
// Only test, test, test, test, test, test!
echo PHP_EOL;
gzclose($zp);
读取操作其实也非常简单,直接使用 gzpassthru() 就可以输出当前压缩包里面的内容,并且是直接打印出来。当然,它也是以类似于文件指针的形式进行输出的,所以如果我们输出过一次之后,就必须要使用 gzrewind() 将指针的游标还原到句柄最开始的位置。
对于 zlib 的压缩包来说,我们还有很多其它的方式可以进行文件内容的读取。
// 读取压缩包二
$gz = gzopen('./gztest.gz', 'r');
while (!gzeof($gz)) {
echo gzgetc($gz);
}
gzclose($gz);
// Only test, test, test, test, test, test!
echo PHP_EOL;
// 读取压缩包三
echo readgzfile("./gztest.gz");
// Only test, test, test, test, test, test!
echo PHP_EOL;
// 读取压缩包四
print_r(gzfile("./gztest.gz"));
// Array
// (
// [0] => Only test, test, test, test, test, test!
// )
echo PHP_EOL;
这里一口气就提供了三种读取的方式。首先当然还是我们最熟悉的文件操作形式的读取,使用的是 zlib 为我们提供的 gzeof() 和 gzgetc() 函数。除了 gzgetc() 之外,也提供了包括 gzgets() 和 gzgetss() ,分别是按行和按 HTML 格式行的读取。其次,我们可以使用 readgzfile() 来直接读取整个压缩文件的内容,连 gzopen() 都可以省了,与它类似的是 gzfile() 函数,这个函数与 readgzfile() 的区别就是它读取的内容是以数组形式返回的,对于多文件的压缩包更有用。
gzip 压缩类型
既然 zlib 所压缩的格式是 .gz 类型,而且还只能做字符串形式的压缩,那么不少小伙伴肯定有疑问了,它和 gzip 有什么关系呢?其实,zlib 除了是可以做为压缩打包工具之外,也可以做为 gzip 工具应用到我们的服务器中。当然,现在大多数情况下我们只需要开启 Nginx 或者 Apache 的 gzip 压缩功能就可以了,不需要我们再到 PHP 中进行处理了。不过做为一名合格的 PHP 程序员,相关的操作函数我们还是需要学习的,说不定哪天就用上了呢。
// 压缩类型及相关操作
// gzcompress 默认使用ZLIB_ENCODING_DEFLATE编码,使用zlib压缩格式,实际上是用 deflate 压缩数据,然后加上 zlib 头和 CRC 校验
$compressed = gzcompress('Compress me', 9);
echo $compressed;
// x�s��-(J-.V�M�?
echo PHP_EOL;
echo gzuncompress($compressed);
// Compress me
echo PHP_EOL;
// gzencode 默认使用ZLIB_ENCODING_GZIP编码,使用gzip压缩格式,实际上是使用defalte 算法压缩数据,然后加上文件头和adler32校验
$compressed = gzencode('Compress me', 9);
echo $compressed;
// s��-(J-.V�M�jM4
echo PHP_EOL;
echo gzdecode($compressed);
// Compress me
echo PHP_EOL;
// gzdeflate 默认使用ZLIB_ENCODING_RAW编码方式,使用deflate数据压缩算法,实际上是先用 LZ77 压缩,然后用霍夫曼编码压缩
$compressed = gzdeflate('Compress me', 9);
echo $compressed;
// s��-(J-.V�M
echo PHP_EOL;
echo gzinflate($compressed);
// Compress me
echo PHP_EOL;
其实注释中已经写得很清晰了,不止是 PHP ,Nginx 也是会提供这三种编码格式的,而且我们从浏览器中就可以看出当前访问的网站使用的是哪种压缩编码格式。比如我们访问 PHP 的官方网站所返回的内容:
从性能的维度看:deflate 好于 gzip 好于 zlib,而从文本文件默认压缩率压缩后体积的维度看:deflate 好于 zlib 好于 gzip 。也就是说,deflate 格式不管在性能还是压缩率来说都是现在比较好的选择。当然,这样好的格式对于 CPU 的硬件性能的影响就不清楚了,毕竟我们没有大型的功能页面来进行测试,起码对于普通的网站页面来说,已经绰绰有余了。
另外,就像其它的压缩工具一样,能够对于字符串进行编码的工具我们都可以扩展一个应用场景,那就是数据的加密能力,这个在前面 Bzip2 、 LZF 相关的这些文章已经说过了,就不再多说了。
最后,我们还有一个通用的函数通过预定义的常量直接可以操作这三种类型的编码及解码。
// 通用压缩函数
$compressed = zlib_encode('Compress me', ZLIB_ENCODING_GZIP, 9);
echo $compressed;
// ZLIB_ENCODING_RAW:s��-(J-.V�M
// ZLIB_ENCODING_DEFLATE:x�s��-(J-.V�M�?
// ZLIB_ENCODING_GZIP:s��-(J-.V�M�jM4
echo PHP_EOL;
echo zlib_get_coding_type();
echo PHP_EOL;
echo zlib_decode($compressed);
// Compress me
echo PHP_EOL;
zlib_encode() 函数的第二个参数就是需要指定一个编码的类型,这里 zlib 扩展已经为我们准备好了 ZLIB_ENCODING_RAW 、 ZLIB_ENCODING_DEFLATE 、 ZLIB_ENCODING_GZIP 这三个类型的常量。而解压 zlib_decode() 则不需要再进行指定了,它会直接根据文件头自动选择相应的编码格式对内容进行解码。
增量压缩操作函数
在 PHP7 中,zlib 扩展为我们增加一种可以增量压缩编码的操作函数,就是可以在不使用对象句柄的情况下,使用函数直接增加内容。
// PHP7 新增的增量压缩操作函数
$deflateContext = deflate_init(ZLIB_ENCODING_GZIP);
$compressed = deflate_add($deflateContext, "数据压缩", ZLIB_NO_FLUSH);
$compressed .= deflate_add($deflateContext, ",更多数据", ZLIB_NO_FLUSH);
$compressed .= deflate_add($deflateContext, ",继续添加更多数据!", ZLIB_FINISH); // ZLIB_FINISH 终止
echo $compressed, PHP_EOL;
// {6uó�uO����Y�~Oϳ�[�.��
// �>߽���϶�~ڵU�h�9
$inflateContext = inflate_init(ZLIB_ENCODING_GZIP);
$uncompressed = inflate_add($inflateContext, $compressed, ZLIB_NO_FLUSH);
$uncompressed .= inflate_add($inflateContext, NULL, ZLIB_FINISH);
echo $uncompressed;
// 数据压缩,更多数据,继续添加更多数据!
就像例子中展示的那样,deflate_add() 用于增量的添加内容到编码文件中,当标志为 ZLIB_FINISH 时结束操作的写入。deflate_init() 和 inflate_init() 分别是编码和反编码对应的初始化操作。
总结
关于压缩解压相关的扩展我们已经介绍了 Bzip2 、 LZF 、 Phar 、 rar 、 zip 和 zlib 这些官方的扩展,在实际的生产中我们其实会比较常用到的是 zip 和 zlib ,当然,对于其它的格式也有了一定的学习了解,剩下的就是我们自己在用到的时候再次的深度研究了。这一个系列的内容让我对这些压缩格式也有了更一步的了解,希望大家也能从中获益。
测试代码:
参考文档:
https://www.php.net/manual/zh/book.zlib.php
https://www.php.cn/php-weizijiaocheng-377246.html
关注公众号:【硬核项目经理】获取最新文章
添加微信/QQ好友:【xiaoyuezigonggong/149844827】免费得PHP、项目管理学习资料
知乎、公众号、抖音、头条搜索【硬核项目经理】
B站ID:482780532
PHP的zlib压缩工具扩展包学习的更多相关文章
- PHP的zip压缩工具扩展包学习
总算到了 PHP 的拿手好戏上场了,前面我们学习过 Bzip2 . LZF . Phar 和 rar 这些压缩相关扩展在 PHP 中的使用,不过它们要么是太冷门,要么就是很多功能不支持.而 Zip 则 ...
- PHP的rar解压读取扩展包学习
作为压缩解压方面的扩展学习,两大王牌压缩格式 rar 和 zip 一直是计算机领域的压缩终结者.rar 格式的压缩包是 Windows 系统中有接近统治地位的存在,今天我们学习的 PHP 扩展就是针对 ...
- Python框架学习之Flask中的常用扩展包
Flask框架是一个扩展性非常强的框架,所以导致它有非常多的扩展包.这些扩展包的功能都很强大.本节主要汇总一些常用的扩展包. 一. Flask-Script pip install flask-scr ...
- Python之扩展包安装
读者朋友,在比较新的版本(Python 2 >=2.7.9 or Python 3 >=3.4)中,pip或者easy_install 扩展包命令已经默认安装(可查看 你的安装目录\p ...
- 【转】下载量最高的 100 个 Laravel 扩展包推荐
说明 Laravel 另一个令人喜欢的地方,是拥有活跃的开发者社区,而活跃的开发者社区带来的,是繁华的扩展包生态. 本文对 Packagist 上打了 Laravel 标签 的扩展包进行整理,截止到现 ...
- R语言扩展包dplyr——数据清洗和整理
R语言扩展包dplyr——数据清洗和整理 标签: 数据R语言数据清洗数据整理 2015-01-22 18:04 7357人阅读 评论(0) 收藏 举报 分类: R Programming(11) ...
- laravel中使用的PDF扩展包——laravel-dompdf和laravel-snappy
这两天项目中需要将HTML页面转换为PDF文件方便打印,我在网上搜了很多资料.先后尝试了laravel-dompdf和laravel-snappy两种扩展包,个人感觉laravel-snappy比较好 ...
- LFD,非官方的Windows二进制文件的Python扩展包
LFD,非官方的Windows二进制文件的Python扩展包 LFD,非官方版本.32和64位.Windows.二进制文件.科学开源.Python扩展包 克里斯托夫·戈尔克(by Christoph ...
- laravel5.5开发composer扩展包
目录 1. 下载laravel框架,并命名(framework) 2. 创建相关目录 3. 项目根目录下的composer.json文件中声明命名空间 4. 在包的根目录(packages/arche ...
随机推荐
- JVM G1GC的算法与实现
G1GC 是什么? 一些基本概念 实时性 G1GC 有什么特点? G1GC 的堆结构是什么样的? G1GC 的执行过程是什么样的? 并发标记 并发标记是什么 标记位图 执行步骤 步骤 1--初始标记阶 ...
- Linux学习手册
入门概述 Linux 简介 Linux 内核最初只是由芬兰人林纳斯·托瓦兹(Linus Torvalds)在赫尔辛基大学上学时出于个人爱好而编写的. Linux 是一套免费使用和自由传播的类 Unix ...
- SpringSession(redis)
pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="htt ...
- Qt迭代器(Java类型和STL类型)详解
迭代器为访问容器类里的数据项提供了统一的方法,Qt 有两种迭代器类:Java 类型的迭代器和 STL 类型的迭代器. 两者比较,Java 类型的迭代器更易于使用,且提供一些高级功能,而 STL 类型的 ...
- Java Web基础 --- Servlet 综述(理论篇)
摘要: Web 技术成为当今主流的互联网 Web 应用技术之一,而 Servlet 是 Java Web 技术的核心基础.本文首先从请求/响应架构应用的大背景谈起 Servlet 的由来,明确 Ser ...
- struts2思想学习(一)
OOP 面向对象编程 AOP 面向切面编程 而在struts2 处处体现了面向切面编程的思想(动态代理最典型)! 拦截器其实也是面向切面编程!拦截器切断了所有请求到action的操作 并做了很多的前提 ...
- VS code快速创建vue模板
忘记了.vue文件的格式或者不想手动敲那段模板代码怎么办?VS code快速创建vue模板帮你偷个小懒 第一步:新建模板并保存 打开 VS code,依次点击 file > Preference ...
- 常见面试题:java8有什么新特性?
常见面试题:java8有什么新特性? 主要有以下这些新特性: lambda 表达式,经常配合函数式接口使用,可以有效减少代码量 Runnable 是一个函数式接口,下面展示了创建线程三种写法,显然最后 ...
- 移动端touch事件——单指拖拽
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...
- 经典深度学习CNN总结 - LeNet、AlexNet、GoogLeNet、VGG、ResNet
参考了: https://www.cnblogs.com/52machinelearning/p/5821591.html https://blog.csdn.net/qq_24695385/arti ...