php 获取文件信息-PHP zip压缩工具扩展包学习

终于,PHP的好戏登场了。 我们学习了Bzip2、LZF、Phar和rar在PHP中的使用,但是它们要么太小php 获取文件信息,要么很多功能不支持。 而Zip是PHP中支持最广泛的功能的一种流行的压缩格式,或者说是一种通用的压缩格式。 当然,这也主要是因为Zip也是Linux环境下事实上的通用压缩格式。

安装

对于 PHP,Zip 扩展已经集成在 PHP 安装包中。 配置时直接添加--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; $inumFiles;$i++) {
    echo "index: $in";
    // 打印每个文件实体信息
    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 获取文件信息,直接获取压缩包中某个文件的内容。 这些函数在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其他内容的朋友可以点击底部链接直接进入指南。

测试代码:

%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

参考文件: