php实现的zip文件内容比较类

这篇文章主要介绍了php实现的zip文件内容比较类及其用法,可实现比较两个zip文件的内容,返回新增、删除、及相同的文件列表,是非常实用的技巧,需要的朋友可以参考下

本文实例讲述了php实现的zip文件内容比较类。是一个非常实用的PHP类文件。分享给大家供大家参考。具体分析如下:

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

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

ZipCompare.class.php类文件如下:

  1. <?php
  2. /** Zip Compare class 比较两个zip文件的内容,返回新增,删除,及相同的文件列表,暂时只支持单层
  3. * Date: 2014-05-18
  4. * Author: fdipzone
  5. * Ver: 1.0
  6. *
  7. * Func:
  8. * public compare 比较zip文件内容
  9. * private getInfo 获取zip内文件列表
  10. * private parse 分析两个zip的文件内容
  11. * private check 检查zip文件是否正确
  12. * private check_handler 检查服务器是否有安装unzip
  13. */
  14. class ZipCompare{ // class start
  15. /** 比较zip文件内容,列出不相同的部分
  16. * @param String $zipfile1 zip文件1
  17. * @param String $zipfile2 zip文件2
  18. * @return Array
  19. */
  20. public function compare($zipfile1, $zipfile2){
  21. // 检查是否有安装unzip
  22. if(!$this->check_handler()){
  23. throw new Exception('unzip not install');
  24. }
  25. // 检查zip文件
  26. if(!$this->check($zipfile1) || !$this->check($zipfile2)){
  27. throw new Exception('zipfile not exists or error');
  28. }
  29. // 获取zip内文件列表
  30. $zipinfo1 = $this->getInfo($zipfile1);
  31. $zipinfo2 = $this->getInfo($zipfile2);
  32. // 分析两个zip的文件内容,返回相同及不同的文件列表
  33. return $this->parse($zipinfo1, $zipinfo2);
  34. }
  35. /** 获取zip内文件列表
  36. * @param String $zipfile zip文件
  37. * @return Array zip内文件列表
  38. */
  39. private function getInfo($zipfile){
  40. // unzip -v fields
  41. $fields = array('Length','Method','Size','Cmpr','Date','Time','CRC-32','Name');
  42. // zip verbose
  43. $verbose = shell_exec(sprintf("unzip -v %s | sed '\$d' | sed '\$d' | sed -n '4,\$p'", $zipfile));
  44. // zip info
  45. $zipinfo = array();
  46. $filelist = explode("\n", $verbose);
  47. if($filelist){
  48. foreach($filelist as $rowdata){
  49. if($rowdata==''){
  50. continue;
  51. }
  52. $rowdata = preg_replace('/[ ]{2,}/', ' ', $rowdata); // 将两个或以上空格替换为一个
  53. $tmp = array_slice(explode(' ', $rowdata), 1); // 去掉第一个空格
  54. $file = array_combine($fields, $tmp);
  55. $zipinfo[$file['Name']] = $file['Length'].'_'.$file['CRC-32']; // 文件名,长度,CRC32,用于校验
  56. }
  57. }
  58. return $zipinfo;
  59. }
  60. /** 分析两个zip文件内容
  61. * @param String $zipinfo1
  62. * @param String $zipinfo2
  63. * @return Array
  64. */
  65. private function parse($zipinfo1, $zipinfo2){
  66. $result = array(
  67. 'add' => array(), // 新增
  68. 'del' => array(), // 缺少
  69. 'match' => array() // 匹配
  70. );
  71. if($zipinfo1 && $zipinfo2){
  72. // 在zip1但不在zip2的文件
  73. $result['add'] = array_values(array_diff(array_keys($zipinfo1), array_keys($zipinfo2)));
  74. // 在zip2但不在zip1的文件
  75. $result['del'] = array_values(array_diff(array_keys($zipinfo2), array_keys($zipinfo1)));
  76. // 同时在zip1与zip2的文件
  77. $match_file = array_values(array_diff(array_keys($zipinfo1), $result['add']));
  78. // 检查相同文件名的文件内容是否匹配
  79. for($i=0,$len=count($match_file); $i<$len; $i++){
  80. if($zipinfo1[$match_file[$i]]==$zipinfo2[$match_file[$i]]){ // match
  81. array_push($result['match'], $match_file[$i]);
  82. }else{ // not match, change to add
  83. array_push($result['add'], $match_file[$i]);
  84. }
  85. }
  86. }
  87. return $result;
  88. }
  89. /** 检查zip文件是否正确
  90. * @param String $zipfile zip文件
  91. * @return boolean
  92. */
  93. private function check($zipfile){
  94. // 文件存在且能解压
  95. return file_exists($zipfile) && shell_exec(sprintf('unzip -v %s | wc -l', $zipfile))>1;
  96. }
  97. //www.phpfensi.com
  98. /** 检查服务器是否有安装unzip
  99. * @return boolean
  100. */
  101. private function check_handler(){
  102. return strstr(shell_exec('unzip -v'), 'version')!='';
  103. }
  104. } // class end
  105. ?>

demo示例程序如下:

  1. <?php
  2. require "ZipCompare.class.php";
  3. $obj = new ZipCompare();
  4. $result = $obj->compare('test1.zip','test2.zip');
  5. print_r($result);
  6. ?>

执行后输出:

  1. Array
  2. (
  3. [add] => Array
  4. (
  5. [0] => 9.jpg
  6. )
  7. [del] => Array
  8. (
  9. [0] => 5.jpg
  10. [1] => 6.jpg
  11. [2] => 7.jpg
  12. [3] => 8.jpg
  13. )
  14. [match] => Array
  15. (
  16. [0] => 1.jpg
  17. [1] => 10.jpg
  18. [2] => 11.jpg
  19. [3] => 12.jpg
  20. [4] => 13.jpg
  21. [5] => 14.jpg
  22. [6] => 15.jpg
  23. [7] => 16.jpg
  24. [8] => 17.jpg
  25. [9] => 18.jpg
  26. [10] => 2.jpg
  27. [11] => 3.jpg
  28. [12] => 4.jpg
  29. )
  30. )