标梵学习PHP的压缩工具扩展包

PHP的zip压缩工具扩展包学习

总算到了 PHP 的拿手好戏上场了,前面我们学习过 Bzip2 、 LZF 、 Phar 和 rar 这些压缩相关扩展在 PHP 中的使用,不过它们要么是太冷门,要么就是很多功能不支持。而 Zip 则是在 PHP 中得到最大幅度功能支持的热门压缩格式,或者说是通用常见的一种压缩格式。当然,也主要得益于 Zip 也是事实上的 Linux 环境中的通用压缩格式。

安装

对于 PHP 来说,Zip 扩展已经集成在了 PHP 的安装包中,在 Configure 的时候可以直接加上 --with-zip ,如果在安装的时候没有加上这个参数,我们也可以在源码包的 ext/zip 下找到源码,然后通过扩展安装的方式进行安装。

创建一个压缩包

$zip = new ZipArchive();

$filename = './test_zip.zip';

if($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE){

exit('cannot open ' . $filename .'\n');

}

// 加入文字类型的文件

$zip->addFromString('testfile1.txt' . time(), "#1");

$zip->addFromString('testfile2.txt' . time(), "#2");

// 加入已存在的文件

$zip->addFile('rar.php', 'newrar.php');

echo $zip->numFiles, PHP_EOL; // 文件数量

echo $zip->status, PHP_EOL; // 压缩包状态

$zip->close();

// 使用操作系统的 unzip 查看

// # unzip -l test_zip.zip

// Archive:  test_zip.zip

//   Length      Date    Time    Name

// ---------  ---------- -----   ----

//         2  07-08-2020 08:57   testfile1.txt1594169845

//         2  07-08-2020 08:57   testfile2.txt1594169845

//      2178  07-07-2020 08:55   newrar2.php

// ---------                     -------

//      2182                     3 files

之前学习过的 rar 扩展是无法打包文件或者创建新的压缩包的,而 Zip 一上来我们就学习的是创建一个新的压缩包。通过实例化一个 ZipArchive 对象后,我们就可以使用 open() 函数打开或创建一个压缩包文件。接着,我们使用了两种添加内容的方式。addFromString() 是加入文字类型的文件,也就是将一段文字转换成文本文件保存在这个压缩包中。另外,我们通过 addFile() 来将外部的文件加入到这个压缩包中。

numFiles 和 status 属性可以分别查看到压缩包文件里面的文件数量及当前这个压缩包的状态信息。最后直接使用 close() 关闭句柄即可。这样,一个简单的 Zip 压缩包文件就创建完成了。我们可以直接使用操作系统的 unzip 命令来查看压缩包的内容。

读取压缩包内容及信息

$zip = new ZipArchive();

$zip->open('./test_zip.zip');

print_r($zip); // 压缩包信息

// ZipArchive Object

// (

//     [status] => 0

//     [statusSys] => 0

//     [numFiles] => 40

//     [filename] => /data/www/blog/test_zip.zip

//     [comment] =>

// )

var_dump($zip);

// object(ZipArchive)#2 (5) {

//     ["status"]=>

//     int(0)

//     ["statusSys"]=>

//     int(0)

//     ["numFiles"]=>

//     int(40)

//     ["filename"]=>

//     string(27) "/data/www/blog/test_zip.zip"

//     ["comment"]=>

//     string(0) ""

//   }

echo $zip->numFiles, PHP_EOL;

echo $zip->status, PHP_EOL;

echo $zip->statusSys, PHP_EOL;

echo $zip->filename, PHP_EOL;

echo $zip->comment, PHP_EOL;

echo $zip->count(), PHP_EOL;

for ($i=0; $i<$zip->numFiles;$i++) {

echo "index: $i\n";

// 打印每个文件实体信息

print_r($zip->statIndex($i));

// index: 0

// Array

// (

//     [name] => testfile1.txt1594169845

//     [index] => 0

//     [crc] => 2930664868

//     [size] => 2

//     [mtime] => 1594169844

//     [comp_size] => 2

//     [comp_method] => 0

//     [encryption_method] => 0

// )

// ……

$entry = $zip->statIndex($i);

if($entry['name'] == 'newrar.php'){

// 仅解压 newrar.php 文件到指定目录

$zip->extractTo('./test_zip_single', $entry['name']);

}

}

// 修改压缩包内的文件名

$zip->renameName('newrar.php', 'newrar2.php');

print_r($zip->getFromIndex(2)); // 获取第二个文件的内容

print_r($zip->getFromName('newrar2.php')); // 获取指定文件名的文件内容

$zip->extractTo('./test_zip'); // 解压整个压缩包到指定目录

$zip->close();

其实读取也是同样的步骤,实例化一个 ZipArchive 类,然后 open() 打开一个压缩包文件句柄。接着就可以直接输出一些压缩包的属性信息。我们可以通过循环并通过 statIndex() 方法获取每个文件实体的信息。这里需要注意的是 statIndex() 获取的是文件的信息,而不是这个文件的内容。

当然,我们也可以通过 getFromIndex() 或 getFromName() 直接获取指定的文件。通过 renameName() 直接给压缩包内部的文件改名,通过 extractTo() 将指定的文件或者整个压缩包解压到指定的目录中。extractTo() 方法的第二个参数如果指定了内容,则只会解压指定的这个文件。

压缩目录,设置说明以及流、伪协议方式读取文件

既然是压缩包工具,那么我们最常用的也就是直接将多个文件或者目录进行打包。同时,也有很多压缩包可以设置一些说明、密码什么的。另外,我们还可以通过专属的 zip:// 伪协议来直接获取压缩包内某个文件的内容。这些功能,在 PHP 的 Zip 扩展中都能够非常简单方便地使用。

压缩目录

// 压缩目录

$zip = new ZipArchive();

$zip->open('./test_zip2.zip', ZIPARCHIVE::CREATE);

$zip->addFile('rar.php', 'newrar.php');

$zip->addGlob('./test_zip/*.{php,txt}', GLOB_BRACE, ['add_path'=> 'new_path/']);

直接使用 addGlob 就可以帮助我们完成对某个文件目录下的所有文件的内容打包。同时,它的第三个参数也可以指定这些文件在压缩包内部的路径地址。

设置说明及密码

// 设置注释、密码

$zip->setArchiveComment('This is rar Comment!');

$zip->setPassword('123');

$zip->close();

// 使用操作系统 unzip 查看

// # unzip -l test_zip2.zip

// Archive:  test_zip2.zip

// This is rar Comment!

//   Length      Date    Time    Name

// ---------  ---------- -----   ----

//      2178  07-07-2020 08:55   newrar.php

//      2178  07-08-2020 10:36   new_path/./test_zip/newrar.php

//      2178  07-08-2020 10:36   new_path/./test_zip/newrar2.php

// ---------                     -------

//      6534                     3 files

设置压缩包的说明注释以及密码都是有现成的函数方法直接使用的。我们再次通过操作系统的 unzip 命令,就可以查看到这个压缩包的注释信息以及打包的目录内容。本来测试的 test_zip/ 目录下的内容被放在了 new_path/ 目录下,这就是我们自定的一个压缩包内部的路径地址。

流、伪协议方式读取文件

// 流、伪协议方法读取压缩包内容

$zip = new ZipArchive();

$zip->open('./test_zip2.zip');

// 获取文件流

$fp = $zip->getStream('newrar.php');

while(!feof($fp)){

echo fread($fp, 2);

}

fclose($fp);

// 使用伪协议

$fp = fopen('zip://' . dirname(__FILE__) . '/test_zip2.zip#newrar.php', 'r');

while(!feof($fp)){

echo fread($fp, 2);

}

fclose($fp);

// file_get_contents 使用伪协议

echo file_get_contents('zip://' . dirname(__FILE__) . '/test_zip2.zip#newrar.php');

// 直接使用伪协议将文件拷贝出来

copy('zip://' . dirname(__FILE__) . '/test_zip2.zip#newrar.php', './newrar2.php');

首先,我们通过 getStream() 方法直接获取压缩包中某个文件的流,这种方式几乎是所有压缩类扩展都会提供的一种读取文件的方式。而下面的方式则是通过 zip:// 伪协议直接使用 fopen() 、 file_get_contents() 函数来读取压缩包内部的某个文件。既然有了这么方便的一个伪协议,那么我们要简单的获取并解压某个文件也就变得十分容易了,直接使用 copy() 函数将这个文件拷贝出来就可以了。

总结

是不是感觉比 rar 的操作强大了许多。都说了这是 PHP 主力支持的一种通用压缩格式,所以当然功能会丰富许多,而且还有很多的函数方法我们并没有全部列出来,如果全列出来的话还不如大家自己去看手册呢。这里就是以一些简单的例子让大家看到这类扩展功能的操作,方便大家在业务选型的时候能够快速的联想到我们 PHP 就已经提供了这些现成的扩展。需要了解 Zip 其它内容的同学可以移步最下方的链接直接进入手册中查阅。

测试代码:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202007/source/PHP%E7%9A%84zip%E5%8E%8B%E7%BC%A9%E5%B7%A5%E5%85%B7%E6%89%A9%E5%B1%95%E5%8C%85%E5%AD%A6%E4%B9%A0.php

参考文档:

https://www.php.net/manual/zh/book.zip.php

文章来源:Biaofun标梵互动(https://www.biaofun.com/)

(0)

相关推荐

  • 一起搞懂PHP的错误和异常(二)

    一起搞懂PHP的错误和异常(二) 上回文章中我们讲到了错误是编译和语法运行时会出现的,它们与逻辑无关,是程序员在码代码时不应该出现的,也就是说,这些错误应该是尽量避免带到线上环境的,他们不能通过try ...

  • use关键字在PHP中的几种用法

    use关键字在PHP中的几种用法 在学习了和使用了这么多年的PHP之后,您知道use这个关键字在PHP中都有哪些用法吗?今天我们就来看一下它的三种常见用法. 1. 用于命名空间的别名引用 // 命名空 ...

  • 关于当前PHP脚本运行时系统信息相关函数

    关于当前PHP脚本运行时系统信息相关函数 我们的 PHP 在执行的时候,其实可以获取到非常多的当前系统相关的信息.就像很多开源的 CMS 一般会在安装的时候来检测一些环境信息一样,这些信息都是可以方便 ...

  • 学习PHP生成器的使用

    学习PHP生成器的使用 什么是生成器? 听着高大上的名字,感觉像是创造什么东西的一个功能,实际上,生成器是一个用于迭代的迭代器.它提供了一种更容易的方式来实现简单的对象迭代,相比较定义类实现Itera ...

  • PHP中的文件系统函数(三)

    PHP中的文件系统函数(三) 总算来到我们最关心的部分了,也就是 f 相关函数的操作.基本上大部分的文件操作都是以今天学习的这些内容为基础的,话不多说,我们就一个一个的来学习学习吧. 文件读取 文件的 ...

  • 静态成员在PHP中是怎么继承的?

    静态成员在PHP中是怎么继承的? 静态成员,也就是用static修饰的变量或者方法,如果搞不清楚它们实现的原理,就很容易会出现一些错误.这次我们来研究的是在继承中静态成员的调用情况.首先来看这样一段代 ...

  • PHP中的那些魔术常量

    之前我们已经了解了一些常用的魔术方法,除了魔术方法外,PHP还提供一些魔术常量,相信大家在日常的工作中也都使用过,这里给大家做一个总结. 其实PHP还提供了很多常量但都依赖于各类扩展库,而有几个常量是 ...

  • PHP的bz2压缩扩展工具

    PHP的bz2压缩扩展工具 在日常的开发和电脑使用中,我们经常会接触到压缩和解压的一些工具,PHP 也为我们准备了很多相关的操作扩展包,都有直接可用的函数能够方便的操作一些压缩解压功能.今天,我们先学 ...

  • 学习PHP中Fileinfo扩展的使用

    学习PHP中Fileinfo扩展的使用 今天来学习的这个扩展其实现在也已经是标配的一个扩展了,为什么呢?因为 Laravel 框架在安装的时候它就是必须的一个扩展,没有打开它的话,连 Laravel ...

  • 关于php的ini文件相关操作函数浅析

    关于php的ini文件相关操作函数浅析 在小公司,特别是创业型公司,整个服务器的搭建一般也是我们 PHP 开发工程师的职责之一.其中,最主要的一项就是要配置好服务器的 php.ini 文件.一些参数会 ...

  • 一起搞懂PHP的错误和异常(三)

    一起搞懂PHP的错误和异常(三) 关于错误与异常的最后一篇文章,我们来进行一些总结. PHP中错误和异常的区别 通过前面两篇文章的学习,我们来直接将错误和异常摆上来进行对比,看看他们的区别与联系: 错 ...

  • PHP中的文件系统函数(一)

    PHP中的文件系统函数(一) 从这篇文章开始,我们将学习一系列的 PHP 文件系统相关函数.其实这些函数中,有很多都是我们经常用到的,大家并不需要刻意地去记住它们,只要知道有这么个东西,在使用的时候记 ...

  • PHP中命名空间是怎样的存在(一)?

    命名空间其实早在PHP5.3就已经出现了.不过大部分同学可能在各种框架的使用中才会接触到命名空间的内容,当然,现代化的开发也都离不开这些能够快速产出的框架.这次我们不从框架的角度,仅从简单的代码角度来 ...

  • PHP的zlib压缩工具扩展包学习

    PHP的zlib压缩工具扩展包学习 总算到了我们压缩相关扩展的最后一篇文章了,最后我们要学习的也是 Linux 下非常常用的一种压缩格式:.gz 的压缩扩展.作为 PHP 的自带扩展,就像 zip 一 ...

  • 后期静态绑定在PHP中的使用

    后期静态绑定在PHP中的使用 什么叫后期静态绑定呢?其实我们在之前的文章PHP中的static中已经说过这个东西了.今天我们还是再次深入的理解一下这个概念. 首先,我们通过一段代码来引入后期静态绑定这 ...

  • PHP的Hash信息摘要扩展框架

    PHP的Hash信息摘要扩展框架 今天我们主要学习的是 PHP 中一些 Hash 散列加密相关的扩展函数的使用,而不是 Hash 算法,这种加密其实也只是一种更复杂一些的密钥算法,与 Hash 算法类 ...

  • 彻底搞明白PHP中的include和require

    在PHP中,有两种包含外部文件的方式,分别是include和require.他们之间有什么不同呢? 如果文件不存在或发生了错误,require产生E_COMPILE_ERROR级别的错误,程序停止运行 ...

  • PHP没有定时器?

    PHP没有定时器? 确实,PHP没有类似于JS中的setInterval或者setTimeout这样的原生定时器相关的函数.但是我们可以通过其他方式来实现,比如使用declare. 先来看看是如何实现 ...

  • PHP中命名空间是怎样的存在?(二)

    PHP中命名空间是怎样的存在?(二) 今天带来的依然是命名空间相关的内容,本身命名空间就是PHP中非常重要的一个特性.所以关于它的各种操作和使用还是非常复杂的,光使用方式就有很多种,我们一个一个的来看 ...

  • 在PHP中灵活使用foreach+list处理多维数组

    先抛出问题,有时候我们接收到的参数是多维数组,我们需要将他们转成普通的数组,比如: $arr = [ [1, 2, [3, 4]], [5, 6, [7, 8]],]; 我们需要的结果是元素1变成1, ...

  • PHP获取目录中的全部内容RecursiveDirectoryIterator

    PHP获取目录中的全部内容RecursiveDirectoryIterator 这次我们来介绍一个SPL库中的目录迭代器,它的作用其实非常简单,从名字就可以看出来,就是获取指定目录下的所有内容.之前我 ...

  • PHP中DirectIO直操作文件扩展的使用

    PHP中DirectIO直操作文件扩展的使用 关于 PHP 的文件操作,我们也将是通过一系列的文章来进行学习.今天我们先学习的是一个很少人使用过,甚至很多人根本不知道的扩展,它与我们日常的文件操作有些 ...

  • PHP的rar解压读取扩展包学习

    PHP的rar解压读取扩展包学习 作为压缩解压方面的扩展学习,两大王牌压缩格式 rar 和 zip 一直是计算机领域的压缩终结者.rar 格式的压缩包是 Windows 系统中有接近统治地位的存在,今 ...

  • PHP中的一些杂项函数学习

    PHP中的一些杂项函数学习 今天来学习的这些杂项函数在官方文档中都是放在一个杂项扩展中的,其实这些函数都并不是什么什么特别的扩展,也不需要安装什么东西就可以使用,它们就是一些简单的功能函数而已.当然, ...