首页  >  文章  >  后端开发  >  关于php zip文件内容比较类的讲解

关于php zip文件内容比较类的讲解

jacklove
jacklove原创
2018-06-09 13:47:442274浏览

php zip 文件比较类,比较两个zip文件的内容,返回新增,删除,及相同的文件列表。暂时只支持单层。

需求:上传一个zip文件,zip内有很多图片文件。需要对图片文件进行一系列很耗时的处理。当用户再更新zip文件时。判断zip内文件是否一致,只处理不同的文件。这样可以节省资源与时间,因此需要编写一个能够比较zip内文件的类。

ZipCompare.class.php

<?php
/** Zip Compare class 比较两个zip文件的内容,返回新增,删除,及相同的文件列表,暂时只支持单层
*   Date:   2014-05-18
*   Author: fdipzone
*   Ver:    1.0
*
*   Func:
*   public  compare       比较zip文件内容
*   private getInfo       获取zip内文件列表
*   private parse         分析两个zip的文件内容
*   private check         检查zip文件是否正确
*   private check_handler 检查服务器是否有安装unzip
*/
class ZipCompare{ // class start
    /** 比较zip文件内容,列出不相同的部分
    * @param  String  $zipfile1 zip文件1
    * @param  String  $zipfile2 zip文件2
    * @return Array
    */
    public function compare($zipfile1, $zipfile2){
        // 检查是否有安装unzip
        if(!$this->check_handler()){
            throw new Exception(&#39;unzip not install&#39;);
        }
        // 检查zip文件
        if(!$this->check($zipfile1) || !$this->check($zipfile2)){
            throw new Exception(&#39;zipfile not exists or error&#39;);
        }
        // 获取zip内文件列表
        $zipinfo1 = $this->getInfo($zipfile1);
        $zipinfo2 = $this->getInfo($zipfile2);
        // 分析两个zip的文件内容,返回相同及不同的文件列表
        return $this->parse($zipinfo1, $zipinfo2);
    }
    /** 获取zip内文件列表
    * @param  String $zipfile zip文件
    * @return Array           zip内文件列表
    */
    private function getInfo($zipfile){
        // unzip -v fields
        $fields = array(&#39;Length&#39;,&#39;Method&#39;,&#39;Size&#39;,&#39;Cmpr&#39;,&#39;Date&#39;,&#39;Time&#39;,&#39;CRC-32&#39;,&#39;Name&#39;);
        // zip verbose
        $verbose = shell_exec(sprintf("unzip -v %s | sed &#39;\$d&#39; | sed &#39;\$d&#39; | sed -n &#39;4,\$p&#39;", $zipfile));
        // zip info
        $zipinfo = array();
        $filelist = explode("\n", $verbose);
        if($filelist){
            foreach($filelist as $rowdata){
                if($rowdata==&#39;&#39;){
                    continue;
                }
                $rowdata = preg_replace(&#39;/[ ]{2,}/&#39;, &#39; &#39;, $rowdata); // 将两个或以上空格替换为一个
                $tmp = array_slice(explode(&#39; &#39;, $rowdata), 1);       // 去掉第一个空格
                $file = array_combine($fields, $tmp);
                $zipinfo[$file[&#39;Name&#39;]] = $file[&#39;Length&#39;].&#39;_&#39;.$file[&#39;CRC-32&#39;]; // 文件名,长度,CRC32,用于校验
            }
        }
        return $zipinfo;
    }
    /** 分析两个zip文件内容
    * @param  String $zipinfo1
    * @param  String $zipinfo2
    * @return Array
    */
    private function parse($zipinfo1, $zipinfo2){
        $result = array(
                &#39;add&#39; => array(),  // 新增
                &#39;del&#39; => array(),  // 缺少
                &#39;match&#39; => array() // 匹配
            );
        if($zipinfo1 && $zipinfo2){
            // 在zip1但不在zip2的文件
            $result[&#39;add&#39;] = array_values(array_diff(array_keys($zipinfo1), array_keys($zipinfo2)));
            // 在zip2但不在zip1的文件
            $result[&#39;del&#39;] = array_values(array_diff(array_keys($zipinfo2), array_keys($zipinfo1)));
            // 同时在zip1与zip2的文件
            $match_file = array_values(array_diff(array_keys($zipinfo1), $result[&#39;add&#39;]));
            // 检查相同文件名的文件内容是否匹配
            for($i=0,$len=count($match_file); $i<$len; $i++){
                if($zipinfo1[$match_file[$i]]==$zipinfo2[$match_file[$i]]){ // match
                    array_push($result[&#39;match&#39;], $match_file[$i]);
                }else{  // not match, change to add
                    array_push($result[&#39;add&#39;], $match_file[$i]);
                }
            }
        }
        return $result;
    }
    /** 检查zip文件是否正确
    * @param  String $zipfile zip文件
    * @return boolean
    */
    private function check($zipfile){
        // 文件存在且能解压
        return file_exists($zipfile) && shell_exec(sprintf(&#39;unzip -v %s | wc -l&#39;, $zipfile))>1;
    }
    /** 检查服务器是否有安装unzip
    * @return boolean
    */
    private function check_handler(){
        return strstr(shell_exec(&#39;unzip -v&#39;), &#39;version&#39;)!=&#39;&#39;;
    }
} // class end
?>

demo

<?php
require "ZipCompare.class.php";
$obj = new ZipCompare();
$result = $obj->compare(&#39;test1.zip&#39;,&#39;test2.zip&#39;);
print_r($result);
?>

执行后输出:

Array
(
    [add] => Array
        (
            [0] => 9.jpg
        )
    [del] => Array
        (
            [0] => 5.jpg
            [1] => 6.jpg
            [2] => 7.jpg
            [3] => 8.jpg
        )
    [match] => Array
        (
            [0] => 1.jpg
            [1] => 10.jpg
            [2] => 11.jpg
            [3] => 12.jpg
            [4] => 13.jpg
            [5] => 14.jpg
            [6] => 15.jpg
            [7] => 16.jpg
            [8] => 17.jpg
            [9] => 18.jpg
            [10] => 2.jpg
            [11] => 3.jpg
            [12] => 4.jpg
        )
)

本篇文章讲解了关于php zip文件内容比较类的讲解,更多相关内容请关注php中文网。

相关推荐:

如何通过php 获取/设置用户访问页面语言类

通过php 计算两个文件之间的相对路径方法

关于php JSON数据格式化的方法

以上是关于php zip文件内容比较类的讲解的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn