使用php操作zip文件(压缩文件为zip及解压zip文件等)

本文中使用的php版本:php7.4.27


单个文件的下载很容易实现,但是批量下载文件的话,虽然说比单文件下载要麻烦一些,但其实也还行。


批量下载文件的原理:将要批量下载的文件 打包压缩为zip文件,然后下载这一个压缩后的zip文件即可。使用php的内置类 ZipArchive() 可以让我们很容易实现文件的压缩和解压等。


注意点:配置php.ini,找到zip模块,并启用即可。咳咳~~ 虽然这个扩展一般都是默认启用的

创建一个新的zip文件

以下代码将创建一个新的zip文件(test_new.zip)并向其中添加一些文件。

$zip = new ZipArchive();

if($zip->open('test_new.zip', ZipArchive::CREATE) === true)
{
    //将文件添加到zip文件
    $zip->addFile('./test.html');
    $zip->addFile('./composer.json');

    //将random.txt文件添加到zip并将其重命名为newfile.txt
    //$zip->addFile('random.txt', 'newfile.txt');

    //将有指定文本的new.txt文件添加到zip文件中(创建了一个new.txt文件添加到zip文件中,new.txt文件里面的内容就是: 哈哈qaq)
    //$zip->addFromString('new.txt', '哈哈qaq');

    // 关闭zip文件
    $zip->close();
}
else
{
    exit("zip文件创建失败");
}

open() 方法

open()方法的功能是打开一个 zip 文件,第一个参数是 文件名,第二个参数是 打开方式,打开方式可以接受一个预定义常量,下面是预定义常量的说明:

  • ZipArchive::OVERWRITE :总是以一个新的压缩包开始,此模式下如果之前已经存在相同的zip文件,则之前的zip文件会被覆盖。

  • ZipArchive::CREATE: 如果不存在 则创建一个zip压缩包。

  • ZipArchive::RDONLY: 只读模式打开压缩包。

  • ZipArchive::EXCL: 如果压缩包已经存在,则出错。

  • ZipArchive::CHECKCONS: 对压缩包执行额外的一致性检查,如果失败则显示错误。

我上面使用的是 ZipArchive::CREATE,也就是如果 zip 文件不存在就创建一个。

addFile() 方法

addFile 方法的功能是把文件添加到 zip 包中。第一个参数是要添加的文件名,第二个参数是添加到 zip 包中的名称。

//我要添加到 zip 包的文件是 log.txt 添加到 zip 包后在 zip 包中查看就是 log-backup.txt,相当于在添加的时候给文件改个名,成功会返回 true,否则返回 false 。
$zip->addFile('log.txt', 'log-backup.txt');

close() 方法

在操作完成后可以使用 close 关闭打开的 zip 包。

往zip文件中,添加多个文件

添加多个文件 除了多次调用addFile()方法外,也可以使用 addGlob() 方法来实现添加,addGlob() 方法 可以根据给定的过滤方式来获取目录下所有符合标准的文件。


下面创建一个 zip 包,然后把当前目录下所有 txt 结尾的文件都添加到 zip 包中:

$zip = new ZipArchive();  //创建ZipArchive类的对象

$zip->open('1.zip', ZipArchive::CREATE);  //打开并创建一个1.zip文件

$zip->addGlob('*.txt'); //把当前目录下所有 .txt 结尾的文件都添加到 1.zip文件中

$zip->close();  //关闭打开的zip文件


如果我要添加当前目录下的所有文件 代码可以这样写:

$zip->addGlob('*');


注意点:addGlob() 方法 只能添加文件,即便用 * 也不会添加目录。

往zip文件中,添加目录

下面创建一个 zip 包,然后添加一个目录到 zip 包中:

$zip = new ZipArchive(); 

$zip->open('1.zip', ZipArchive::CREATE);

$zip->addEmptyDir('temp');

$zip->close();

上面的 addEmptyDir() 方法只能添加目录,目录中的文件或目录是不会被添加到 zip 包中的,也就是说添加到 zip 包中的是空目录。因为 ZipArchive这个类中,没有可以自动递归添加目录下的文件或目录的方法,所以,如果要添加目录下的文件或目录就只能自己手动递归添加。


简单编写一个可以递归添加目录下的所有文件或目录的类:

class Zip
{
    protected $zip   = null;  // ZipArchive 对象
    protected $count = 0;  // 记录文件数量

    //添加单个文件或目录
    public function add($fileName, $zipFileName = '')
    {
        if($zipFileName == '')
        {
            //如果zip文件名为空就使用传入的文件或目录名作为 zip 文件名
            $zipFileName = $fileName . '.zip';
        }

        $this->zip = new ZipArchive(); //创建ZipArchive类的对象

        $this->zip->open($zipFileName, ZipArchive::CREATE);  //打开一个zip文件

        //判断传入的是否是一个目录
        if(is_dir($fileName))
        {
            $this->addDir($fileName);  //调用添加目录方法
        }
        else
        {
            //如果不是目录就直接添加文件
            if($this->zip->addFile($fileName))
            {
                $this->count ++;  //成功添加后添加文件数量 +1
            }
        }

        $this->zip->close();  //关闭打开的 zip 包

        return $this->count;  //返回已添加文件的数量
    }

    //添加目录
    public function addDir($dir)
    {
        $this->zip->addEmptyDir($dir);  //添加目录

        $fileList = glob($dir .  '/*');  //获取路劲下的所有文件或目录

        foreach($fileList as $file)
        {
            //是否是目录
            if(is_dir($file)) 
            {
                $this->addDir($file);  //调用自身继续操作(这里就是递归点了)
                continue;  //跳过本次循环
            }
            
            //添加文件
            if($this->zip->addFile($file, $file)) 
            {
                $this->count ++;  //成功添加后添加文件数量 +1
            }
        }
    }
}

上面封装的Zip类 可以调用 add() 方法来添加文件或目录,第一个参数 可以传入要添加的文件或目录,第二个参数是 zip包名称,如果传入的 zip 包不存在就会自动创建,如果省略第二个参数会使用文件名来作为 zip 包名。


下面调用一下上面封装的Zip 类:

$zip = new Zip();

$zip->add('src', 'src.zip');  // 调用 add 添加

使用上面的Zip类 无论传入的目录下 有多少文件或目录都能添加到zip文件里面去。

解压文件的相关方法及使用示例

下面把 src.zip 里的所有文件解压到 dir 目录:

$zip = new ZipArchive();  //创建ZipArchive类的对象

$zip->open('src.zip');  //打开 zip 包

$zip->extractTo('dir');  //把 zip 包内的所有文件解压到dir目录

$zip->close();  //关闭打开的 zip 包

解压文件使用的就是 extractTo() 方法,参数就是存放解压后的文件的目录,如果传入的目录不存在会自动创建。extractTo 成功返回 true ,失败返回 false 。

设置和获取注释

使用 WinRAR 等之类的压缩软件,可以查看一些网上下载的压缩包的时候 可以看到右侧有注释内容,PHP 内置的ZipArchive类,也能设置和查看注释内容。


下面给 src.zip 设置注释内容:

$zip = new ZipArchive();  
$zip->open('src.zip');  
$zip->setArchiveComment('这是一个 zip 压缩包');  //设置注释
$zip->close();

setArchiveComment()方法 可以给打开的压缩包设置注释内容,参数就是 注释内容,成功返回 true,失败返回 false 。


下面输出 src.zip 的注释内容:

$zip = new ZipArchive(); 
$zip->open('src.zip'); 
echo $zip->getArchiveComment();  //输出 注释内容
$zip->close();

查询相关方法及使用示例

count() 方法

count方法可以获取压缩包中的文件和目录数量,获取的是所有文件和目录的数量,包括深层级的目录和文件。

getNameIndex() 方法

getNameIndex 方法 可以根据传入的索引返回压缩包内文件的文件名,需要传入一个数字索引,返回对应文件的文件名。


下面循环输出 src.zip 里所有文件的文件名:

$zip = new ZipArchive();  
$zip->open('src-all.zip'); 

for($i = 0; $i < $zip->count(); $i ++) 
{
    echo $zip->getNameIndex($i) . "/n";  //输出文件名
}

$zip->close();

getFromIndex() 方法

getFromIndex 方法可以根据索引读取压缩包内的文件内容,第一个参数是文件索引,第二个参数是读取的字节数,0 为读取整个文件。


下面读取并输出 src.zip 中的第 2 个文件的内容,只读取 3 个字节:

$zip = new ZipArchive();

$zip->open('src.zip');  

echo $zip->getFromIndex(2, 3);  //读取并输出

$zip->close();

getFromName() 方法

getFromName 方法可以根据压缩包内的文件名读取压缩包内的文件内容,第一个参数是要读取的文件名,第二个参数是读取的字节数,0 为读取整个文件。getFromName 和上面的 getFromIndex 方法都是差不多的,只是 getFromName 方法传入的是文件名。

操作压缩包内的文件 的相关方法及使用示例

下面是一些操作压缩包内的文件的方法:

renameName() 方法

renameName 方法可以给压缩包内的文件重命名,第一个参数是要重命名的文件名,第二个参数是新文件名,成功返回 true ,失败返回 false 。


下面把 src.zip 里的 log.txt 重命名为 new-name.txt :

$zip = new ZipArchive();  

$zip->open('src.zip'); 

$zip->renameName('log.txt', 'new-name.txt'); //重命名,将src.zip里的 log.txt 重命名为 new-name.txt :

$zip->close();

renameIndex() 方法

renameIndex 方法和上面的 renameName 方法差不多,也是给压缩包里的文件重命名的,不过 renameIndex 的第一个参数是要重命名的文件索引,第二个参数是新文件名,成功返回 true ,失败返回 false

deleteName() 方法

deleteName 方法可以删除压缩包内的文件, 参数就是要删除的文件名,成功返回 true ,失败返回 false


下面删除 src.zip 中的 log.txt :

$zip = new ZipArchive(); 

$zip->open('src.zip'); 

$zip->deleteName('log.txt');  //删除src.zip压缩包里面的 log.txt文件

$zip->close();

deleteIndex() 方法

deleteIndex 方法和上面的 deleteName 差不多,也是删除压缩包里的文件,不过 deleteIndex 需要传入文件索引。


以上就是 PHP 操作 zip 压缩文件的常用的一些相关方法,更多方法可以查看 PHP 官网的 ZipArchive类 说明。



声明:禁止任何非法用途使用,凡因违规使用而引起的任何法律纠纷,本站概不负责。

小周博客
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

精彩评论

全部回复 0人评论 7,777人参与

loading