PHP压缩和解压缩文件的三种方式

5,727 阅读5分钟

前言:平时在项目中,偶尔会遇到文件备份导入导出的需求,在此记录使用PHP执行文件压缩和解压缩的三种方式**

目录

1. 使用PHP扩展的ZipArchive类

2. 使用压缩与解压缩类PclZip.php

3. 使用PHP函数exec()执行Linux下的压缩zip,解压缩unzip命令


1. 使用PHP扩展的ZipArchive类

使用之前要将php.ini文件中的zlib.output_compression设置为On 配置参考

  • 示例:
function addFileToZip($path, $current, $zip) {
        // 打开文件夹资源
        $handler = opendir($path);
        // 循环读取文件夹内容
        while(($filename = readdir($handler)) !== false) {
            // 过滤掉Linux系统下的.和..文件夹
            if ($filename != '.' && $filename != '..') {
                // 文件指针当前位置指向的如果是文件夹,就递归压缩
                if (is_dir($path.'/'.$filename)) {
                    addFileToZip($path.'/'.$filename, $filename, $zip);
                } else {
                    // 为了在压缩文件的同时也将文件夹压缩,可以设置第二个参数为文件夹/文件的形式,文件夹不存在自动创建压缩文件夹
                    $zip->addFile($path.'/'.$filename, $current.'/'.$filename);
                }
            }
        }
        @closedir($handler);
    }
    $zipName = '生成压缩文件的路径';
// 如果压缩文件不存在,就创建压缩文件
        if (! is_file($zipName)) {
            $fp = fopen($zipName, 'w');
            fclose($fp);
        }
        $zip = new \ZipArchive();
        // OVERWRITE选项表示每次压缩时都覆盖原有内容,但是如果没有那个压缩文件的话就会报错,所以事先要创建好压缩文件
        // 也可以使用CREATE选项,此选项表示每次压缩时都是追加,不是覆盖,如果事先压缩文件不存在会自动创建
        if ($zip->open($zipName, \ZipArchive::OVERWRITE) === true) {
      	$current = '你要压缩的文件的主目录';
            $compress->addFileToZip($path, $current, $zip);
            $zip->close();
        } else {
            exit('打开zip文件失败!');
        }
?>

2. 使用压缩与解压缩类PclZip.php

PclZip library能够压缩与解压缩Zip格式的压缩档(WinZip、PKZIP);且能对此类类档案进行处理,包括产生压缩档、列出压缩档的内容以及解压缩档案等等。由于能够在伺服器端进行压缩与解压缩的动作,所以相当方便使用。 PclZip定义一个PclZip类别,其类别物件可视为一个ZIP档案,亦提供method来进行处理。

  • 示例:
<?php
    // 加载类文件
    require_once('PclZip.php');

    // 初始化类
    $zip = new PclZip("archive.zip");
    $result = $zip->create($_SERVER['DOCUMENT_ROOT'],PCLZIP_OPT_REMOVE_PATH,$_SERVER['DOCUMENT_ROOT']);
    if($result == 0){
        echo '异常信息:'.$z->errorInfo(true);}
    else{
        echo '成功';
    }
?>
  • 其它使用方法
<?php

    // 解压缩到extract/folder/这个目录中      
    $result = $archive->extract(PCLZIP_OPT_PATH,"extract/folder/");      

    // 增加这个目录在压缩档中,完成以后压缩档里面会有backup这个目录,backup里面会有这两个档案      
    $result = $archive->create("file.txt,image.gif",PCLZIP_OPT_ADD_PATH,"backup");      

    // 去掉部份的路径,这里完成后会变成test/file.txt      
    $result = $archive->add("/usr/local/user/test/file.txt",PCLZIP_OPT_REMOVE_PATH,"/usr/local/user");      

    // 把所有路径都去掉,这个压缩档建立完后,里面就只会有file.txt跟image.gif,不会有目录了      
    $result = $archive->create("data/file.txt images/image.gif",PCLZIP_OPT_REMOVE_ALL_PATH);      

    // 把解压缩出来的档案的CHMOD设成0777      
    $result = $archive->extract(PCLZIP_OPT_SET_CHMOD,0777);      

    // 解压缩部份的档案,这个参数是使用档案名称判别      
    // 引数可以用下面这样的阵列      
    $list = array('test/abc.txt', 'test/efg.txt');   
    // 或是下面这样,一个字串中,用逗号分隔每个要解压缩的档案      
    $list = "test/abc.txt,test/efg.txt";      
    $result = $archive->extract(PCLZIP_OPT_BY_NAME, $list);      

    //解压缩部份的档案,使用php的ereg()函式,档案名称有比对成功的都会被解压缩      
    $result = $archive->extract(PCLZIP_OPT_BY_EREG,"aa");      

    // 解压缩部份的档案,使用php的preg_match()函式,档案名称有比对成功的都会被解压缩      
    $result = $archive->extract(PCLZIP_OPT_BY_PREG,"/^bb/");          

    // 依照阵列中元素的索引解压缩   
    $result = $archive->extract(PCLZIP_OPT_BY_INDEX,array('0-1','6-7'));      

    // 将一个档案内容解压缩成一个字串      
    $result = $archive->extract(PCLZIP_OPT_BY_NAME,"data/readme.txt",PCLZIP_OPT_EXTRACT_AS_STRING);      

    // 将一个档案内容解压缩完后直接输出(echo)      
    $result = $archive->extract(PCLZIP_OPT_BY_NAME,"data/readme.txt",PCLZIP_OPT_EXTRACT_IN_OUTPUT);      

    // 将一个档案加入一个压缩档中,但不会对此档案压缩      
    $result = $archive->add("data/file.txt", PCLZIP_OPT_NO_COMPRESSION);      

    // 对此压缩档增加一个注解,如果原本就有注解的话会被覆盖掉      
    $result = $archive->create("data", PCLZIP_OPT_COMMENT,"Add a comment");      

    // 对此压缩档增加一个注解,如果原本就有注解的话会接在后面      
    $result = $archive->add("data", PCLZIP_OPT_ADD_COMMENT,"Add a comment after the existing one");      

    // 对此压缩档增加一个注解,如果原本就有注解的话会放在原本的注解前面      
    $result = $archive->add("data", PCLZIP_OPT_PREPEND_COMMENT,"Add a comment before the existing one");     
?>

3. PHP自带函数exec()执行Linux下的压缩zip,解压缩unzip命令

exec — 执行一个外部程序 (PHP 4, PHP 5, PHP 7)

  • 语法:exec ( string command [, array &output [, int &$return_var ]] ) : string

command:	要执行的shell 命令output: shell命令的输出填充此数组,每行输出填充数组中的一个元素。 请注意,如果数组中已经包含了部分元素,exec() 函数会在数组末尾追加内容。如果你不想在数组末尾进行追加,请在传入 exec() 函数之前 对数组使用 unset() 函数进行重置。 $return_var: 命令执行后的返回状态,命令执行成功值是0。

当然也可以使用system()函数

  • 示例:
exec("zip -P $password $zipFile $fileList", $outputs, $rc);
//参数讲解:
//	-P,加密压缩,解压的时候会询问密码
//	$password,文件压缩自定义密码
//  $zipFile,压缩生成的文件路径
//  $fileList,需要压缩的文件路径字符串,多个时逗号隔开
exec("zip -P $password -m $zipFile $addfile", $outputs, $rc);// -m,将$addfile文件加入$zipFile压缩文件中
exec("zip -P $psw -d $zipFile $removeFile", $outputs, $rc);// -d,从压缩文件$zipFile内删除指定的文件$removeFile

exec("unzip -P $password -o $zipFile -d $unzipFilePath", $outputs, $rc);
//  -o,不必先询问用户,unzip执行后覆盖原有文件
//  -d,指定解压路径

  • 常用参数: zip
-r 递归,将指定目录下的所有文件和子目录一并处理

-S 包含系统和隐藏文件

-y 直接保存符号连接,而非该连接所指向的文件

-X 不保存额外的文件属性

-m 将文件压缩并加入压缩文件后,删除源文件

-<压缩级别> 1~9,数字越大,压缩率越高

-F 尝试修复已损坏的压缩文件

-T 检查备份文件内的每个文件是否正确无误

-q 不显示指令执行过程

-g 将文件压缩后附加在既有的压缩文件之后,而非另行建立新的压缩文件

-u 更新压缩包内文件

-f 更新压缩包内文件。如果符合条件的文件没有包含在压缩包中,则压缩后添加

-$ 保存第一个被压缩文件所在磁盘的卷标

-j 只保存文件名称及其内容

-D 压缩文件内不建立目录名称

-i <表达式> 压缩目录时,只压缩符合条件的文件

-x <表达式> 排除符合条件的文件

-n <文件名后缀> 排除指定文件名后缀的文件

-b <缓存路径> 指定临时文件目录

-d <表达式> 从压缩文件内删除指定的文件

-t <日期时间> 把压缩文件的日期设成指定的日期

-o 以压缩文件内拥有最新更改时间的文件为准,将压缩文件的更改时间设成和该文件相同

-A 调整可执行的自动解压缩文件

-c 替每个被压缩的文件加上注释

-z 替压缩文件加上注释

-k 使用MS-DOS兼容格式的文件名称。

-l 压缩文件时,把LF字符置换成LF+CR字符。

-ll 压缩文件时,把LF+CR字符置换成LF字符。

unzip

-d <路径> 指定解压路径

-n 解压缩时不覆盖原有文件

-f 覆盖原有文件

-o 不经询问,直接覆盖原有文件

-u 覆盖原有文件,并将压缩文件中的其他文件解压缩到目录中

-l 显示压缩文件内所包含的文件

-t 检查压缩文件是否正确

-z 显示压缩包注释

-Z unzip -Z等于执行zipinfo指令

-j 不处理压缩文件中原有的目录路径

-C 压缩文件中的文件名称区分大小写

-L 将压缩文件中的全部文件名改为小写

-s 将文件名中的空格转换下划线

-X 解压缩时保留文件原来的UID/GID

-q 执行时不显示任何信息

-v 执行是时显示详细的信息

-c 将解压缩的结果显示到屏幕上,并对字符做适当的转换

-p 与-c参数类似,会将解压缩的结果显示到屏幕上,但不会执行任何的转换

-a 对文本文件进行必要的字符转换

-b 不要对文本文件进行字符转换

-x <表达式> 处理里排除压缩包中的指定文件

-M 将输出结果送到more程序处理