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

PHP Zip 壓縮檔操作完全指南:安裝、核心函數與實戰應用

     編輯:PHP 入門

PHP Zip 擴展深度解析:壓縮檔讀取、建立、解壓縮與進階操作

PHP Zip 擴展提供完整的 ZIP 壓縮檔處理能力,支援讀取、建立、解壓縮、加密、註解編輯等操作。本文詳細說明安裝配置、核心 API (ZipArchive 物件導向介面與傳統函數式介面)、實戰範例與常見問題對策。

安裝與啟用

驗證:php -m | grep zip 或 extension_loaded('zip')

兩套 API 介面比較

平台安裝方式
Windows (PHP 5.3+)預設內建,確認 php.ini 啟用 extension=zip
Linux (Debian/Ubuntu)apt-get install php-zip
Linux (RHEL/CentOS)yum install php-zip
macOS (Homebrew)brew install php (預設含 zip)
Dockerdocker-php-ext-install zip
從原始碼編譯--enable-zip (PHP 7.3 前) / --with-zip (PHP 7.4+)

ZipArchive 核心方法速查

特性ZipArchive (OO)傳統函數式
風格物件導向程序式
功能完整度完整 (加密、註解、屬性修改)基礎讀取
錯誤處理回傳 bool/狀態碼 + getStatusString()回傳資源/false
記憶體管理自動管理手動 zip_close()
推薦度強烈推薦維舊代碼相容

實戰範例集

1. 建立壓縮檔 (資料夾打包)

function createZipFromDir($sourceDir, $outputZip) {
    $zip = new ZipArchive();
    if ($zip->open($outputZip, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
        throw new Exception("無法建立壓縮檔: $outputZip");
    }

    $sourceDir = rtrim($sourceDir, '/\\');
    $files = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($sourceDir, RecursiveDirectoryIterator::SKIP_DOTS),
        RecursiveIteratorIterator::SELF_FIRST
    );

    foreach ($files as $file) {
        $filePath = $file->getPathname();
        $relativePath = substr($filePath, strlen($sourceDir) + 1);

        if ($file->isDir()) {
            $zip->addEmptyDir($relativePath);
        } else {
            $zip->addFile($filePath, $relativePath);
        }
    }

    $zip->close();
    return true;
}

// 使用
createZipFromDir('/path/to/source', '/path/to/archive.zip');

2. 解壓縮到指定目錄

function extractZip($zipPath, $destDir) {
    $zip = new ZipArchive();
    $res = $zip->open($zipPath);
    if ($res !== true) {
        throw new Exception("無法開啟壓縮檔: $zipPath (錯誤碼: $res)");
    }

    // 可選:只解壓特定項目
    // $zip->extractTo($destDir, ['file1.txt', 'folder/']);

    $zip->extractTo($destDir);
    $zip->close();
    return true;
}

3. 讀取壓縮檔內容不解壓 (記憶體高效)

function readZipEntry($zipPath, $entryName) {
    $zip = new ZipArchive();
    if ($zip->open($zipPath) !== true) return false;

    // 方法 1: 完整讀入記憶體 (小檔案)
    $content = $zip->getFromName($entryName);

    // 方法 2: 串流讀取 (大檔案)
    // $stream = $zip->getStream($entryName);
    // $content = stream_get_contents($stream);
    // fclose($stream);

    $zip->close();
    return $content;
}

4. 列出壓縮檔所有項目資訊

function listZipContents($zipPath) {
    $zip = new ZipArchive();
    if ($zip->open($zipPath) !== true) return [];

    $list = [];
    for ($i = 0; $i < $zip->count(); $i++) {
        $stat = $zip->statIndex($i);
        $list[] = [
            'name' => $stat['name'],
            'size' => $stat['size'],
            'comp_size' => $stat['comp_size'],
            'crc32' => sprintf('%08X', $stat['crc']),
            'mtime' => date('Y-m-d H:i:s', $stat['mtime']),
            'method' => $stat['comp_method'], // 0=store, 8=deflate, 12=bzip2, 14=lzma, 98=zstd
            'is_dir' => substr($stat['name'], -1) === '/'
        ];
    }
    $zip->close();
    return $list;
}

5. 加密壓縮檔 (PHP 7.2+)

function createEncryptedZip($files, $outputZip, $password) {
    $zip = new ZipArchive();
    if ($zip->open($outputZip, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
        throw new Exception("建立失敗");
    }

    $zip->setPassword($password);
    foreach ($files as $name => $content) {
        $zip->addFromString($name, $content);
        $zip->setEncryptionName($name, ZipArchive::EM_AES_256, $password);
    }

    $zip->close();
    return true;
}

6. 記憶體建立壓縮檔並直接輸出下載 (不落地)

function streamZipDownload($files, $filename = 'download.zip') {
    // 需啟用 zlib.output_compression = Off
    $tempZip = 'php://temp';
    $zip = new ZipArchive();
    if ($zip->open($tempZip, ZipArchive::CREATE) !== true) {
        throw new Exception("記憶體建立失敗");
    }

    foreach ($files as $name => $content) {
        $zip->addFromString($name, $content);
    }
    $zip->close();

    // 重新開啟讀取
    $zip->open($tempZip);
    header('Content-Type: application/zip');
    header("Content-Disposition: attachment; filename=\"$filename\"");
    header('Content-Length: ' . $zip->statIndex(0)['size']); // 近似值
    echo $zip->getFromIndex(0); // 實際需迴圈輸出所有項目,或使用串流
    $zip->close();
}

傳統函數式 API (舊代碼維護)

方法說明
open($filename, $flags)開啟壓縮檔,ZipArchive::CREATE、OVERWRITE、EXCL、CHECKCONS
close()關閉並寫入磁碟
addFile($path, $localname)加入檔案
addFromString($name, $content)從字串加入
addGlob($pattern, $flags, $options)依模式批量加入
addPattern($pattern, $path, $options)依正則批量加入
extractTo($destination, $entries)解壓縮到目錄
getFromName($name)讀取項目內容 (字串)
getFromIndex($index)按索引讀取內容
getStream($name)取得資源串流 (大檔案)
deleteName($name)刪除項目
renameName($old, $new)重新命名
setPassword($password)設定解密密碼 (PHP 7.2+)
setEncryptionName($name, $method, $password)設定項目加密 (PHP 7.2+)
count()項目數量
statName($name)取得項目資訊 (大小、壓縮大小、CRC、時間、壓縮方法)
locateName($name)查找項目索引
getNameIndex($index)索引轉名稱
setCommentName($name, $comment)設定項目註解
getCommentName($name)取得項目註解
setArchiveComment($comment)設定壓縮檔註解
getArchiveComment()取得壓縮檔註解

常見問題與限制

函數說明
zip_open($path)開啟壓縮檔,回傳資源
zip_read($zip)讀取下一個項目
zip_entry_open($zip, $entry, $mode)開啟項目讀取
zip_entry_read($entry, $length)讀取項目內容
zip_entry_close($entry)關閉項目
zip_close($zip)關閉壓縮檔
zip_entry_name($entry)取得項目名稱
zip_entry_filesize($entry)原始大小
zip_entry_compressedsize($entry)壓縮大小
zip_entry_compressionmethod($entry)壓縮方法

總結

PHP Zip 擴展透過 ZipArchive 提供功能完整、記憶體安全的壓縮檔操作介面。掌握建立、讀取、解壓縮、加密、串流處理等核心模式,即可滿足檔案打包下載、上傳解壓、資料備份、文件交換等多數業務需求。大檔案、高併發場景建議結合串流 API 與非同步處理佇列。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
問題說明/對策
大檔案記憶體耗盡使用 getStream() 串流處理,避免 getFromName() 全讀入記憶體
中文檔名亂碼PHP 8.0+ 支援 UTF-8 檔名;舊版需手動轉碼或使用 zip_entry_name 讀取原始位元組
壓縮等級控制ZipArchive 無直接設定,需編譯時指定 --with-libzip 並使用 setCompressionIndex() (PHP 8.0+)
4GB+ 壓縮檔需 Zip64 支援 (libzip 1.6+,PHP 7.3+),開啟時加 ZipArchive::CREATE | ZipArchive::OVERWRITE
加密相容性AES-256 需解壓工具支援 (7-Zip, WinRAR, macOS Finder 皆支援)
權限保留ZipArchive 不保留 Unix 權限,需自行記錄恢復