首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP ZIP 檔案比較類別:快速找出新增、刪除、相同檔案(單層結構)

     編輯:PHP 相關知識

前言

當使用者上傳 ZIP 壓縮檔(如大量圖片),後端需對檔案進行耗時處理。若使用者再次上傳更新後的 ZIP,比對兩個 ZIP 內容差異,僅處理變動檔案,可大幅節省資源。本文提供 ZipCompare 類別,呼叫系統 unzip -v 解析 ZIP 目錄,比對檔案名、大小、CRC32,回傳新增、刪除、相同三類清單。

類別功能

  • compare($zipfile1, $zipfile2):回傳陣列 ['add'=>[], 'del'=>[], 'match'=>[]]
  • 依賴伺服器安裝 unzip 指令(Linux 環境)
  • 目前僅支援單層 ZIP 結構(無子目錄)
  • 比對依據:檔案名 + 大小 + CRC32(內容相同)

核心類別程式碼

<?php
class ZipCompare {
    public function compare($zipfile1, $zipfile2) {
        if(!$this->check_handler()) throw new Exception('unzip not install');
        if(!$this->check($zipfile1) || !$this->check($zipfile2)) throw new Exception('zipfile not exists or error');
        $zipinfo1 = $this->getInfo($zipfile1);
        $zipinfo2 = $this->getInfo($zipfile2);
        return $this->parse($zipinfo1, $zipinfo2);
    }
    private function getInfo($zipfile) {
        $fields = array('Length','Method','Size','Cmpr','Date','Time','CRC-32','Name');
        $verbose = shell_exec(sprintf("unzip -v %s | sed '\$d' | sed '\$d' | sed -n '4,\$p'", $zipfile));
        $zipinfo = array();
        foreach(explode("\n", $verbose) as $row) {
            if(!$row) continue;
            $row = preg_replace('/[ ]{2,}/', ' ', $row);
            $tmp = array_slice(explode(' ', $row), 1);
            $file = array_combine($fields, $tmp);
            $zipinfo[$file['Name']] = $file['Length'].'_'.$file['CRC-32'];
        }
        return $zipinfo;
    }
    private function parse($zipinfo1, $zipinfo2) {
        $result = array('add'=>array(), 'del'=>array(), 'match'=>array());
        if($zipinfo1 && $zipinfo2) {
            $result['add'] = array_values(array_diff(array_keys($zipinfo1), array_keys($zipinfo2)));
            $result['del'] = array_values(array_diff(array_keys($zipinfo2), array_keys($zipinfo1)));
            $match_file = array_values(array_diff(array_keys($zipinfo1), $result['add']));
            foreach($match_file as $f) {
                if($zipinfo1[$f]==$zipinfo2[$f]) $result['match'][]=$f;
                else $result['add'][]=$f; // 同名但內容不同視為新增
            }
        }
        return $result;
    }
    private function check($zipfile) { return file_exists($zipfile) && shell_exec(sprintf('unzip -v %s | wc -l', $zipfile))>1; }
    private function check_handler() { return strstr(shell_exec('unzip -v'), 'version')!==false; }
}
?>

使用範例

<?php
require "ZipCompare.class.php";
$obj = new ZipCompare();
$result = $obj->compare('test1.zip','test2.zip');
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 ... [12] => 4.jpg )
)

適用場景與限制

  • 適用:圖片批次處理、靜態資源同步、部署套件差異比對
  • 限制:需 Linux + unzip 指令;單層結構;大量檔案時 shell_exec 效能較低
  • 替代方案:PHP 內建 ZipArchive 類別可純 PHP 解析 ZIP,支援多層目錄,適合跨平台需求

改進建議

  1. 改用 ZipArchive 移除外部指令相依
  2. 支援遞迴比對子目錄
  3. 加入修改時間比對選項
  4. 提供介面供前端顯示差異報表

結語

ZipCompare 以系統指令快速實現 ZIP 內容差異比對,適合 Linux 環境下的批次處理前置過濾。若需跨平台或處理複雜目錄結構,建議改用 ZipArchive 純 PHP 實作。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved