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

PHP 制作 ZIP 壓縮文件:PHPZip 類使用指南與現代替代方案

     編輯:PHP 相關知識

前言

早期 PHP 無內建 ZIP 支援,開發者常用第三方類(如 PHPZip、PclZip)純 PHP 實現壓縮。現代 PHP (5.2+) 內建 ZipArchive 類(需編譯 --enable-zip),效能遠超純 PHP 實現。本文介紹 PHPZip 類用法(歷史參考),並重點推薦 ZipArchive 及第三方庫 chumper/zipper、maennchen/zipstream-php 的現代最佳實踐。

PHPZip 類歷史用法(參考)

<?php
require_once 'phpzip.class.php';

$zip = new PHPZip();

// 方法一:壓縮整個目錄(含子目錄)
$zip->Zip('', 'backup_full.zip'); // 當前目錄

// 方法二:壓縮指定文件列表
$files = ['1.txt', 'gb.txt', '5.txt'];
$zip->Zip($files, 'backup_files.zip');

// 方法三:壓縮指定目錄
$zip->Zip('/usr/local/sext/', 'backup_dir.zip');
?>

缺點:純 PHP 實現、大文件極慢、記憶體佔用高、不支援加密、停止維護。

現代標準:ZipArchive 類

安裝啟用

# Ubuntu/Debian
apt-get install php-zip
# 或編譯 PHP 時添加 --enable-zip (PHP 7.3 前) / --with-zip (PHP 7.4+)
# PHP 8.0+ 內建,無需額外編譯參數

基礎操作

<?php
$zip = new ZipArchive();
$filename = 'backup.zip';

// 創建新壓縮包
if ($zip->open($filename, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
    die('無法創建壓縮包');
}

// 添加文件(保留相對路徑)
$zip->addFile('data/report.pdf', 'report.pdf');
$zip->addFile('images/logo.png', 'assets/logo.png');

// 添加目錄遞歸
function addDir(ZipArchive $zip, string $dir, string $prefix = '') {
    $items = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS)
    );
    foreach ($items as $item) {
        $localPath = $prefix . $item->getPathname();
        $relativePath = $prefix . substr($item->getPathname(), strlen($dir) + 1);
        if ($item->isDir()) {
            $zip->addEmptyDir($relativePath);
        } else {
            $zip->addFile($localPath, $relativePath);
        }
    }
}

addDir($zip, '/var/www/html/uploads', 'uploads/');

// 設置註釋
$zip->setArchiveComment('備份於 ' . date('Y-m-d H:i:s'));

// 關閉並寫入磁盤
$zip->close();
echo "壓縮完成: $filename";
?>

解壓縮

<?php
$zip = new ZipArchive();
if ($zip->open('backup.zip') === true) {
    $zip->extractTo('/var/www/html/restore/');
    $zip->close();
    echo '解壓完成';
} else {
    echo '打開失敗';
}
?>

加密與密碼保護 (PHP 7.2+ / libzip 1.2+)

<?php
$zip = new ZipArchive();
$zip->open('secure.zip', ZipArchive::CREATE);
$zip->addFile('secret.txt');
$zip->setEncryptionName('secret.txt', ZipArchive::EM_AES_256, 'strong_password_123');
$zip->close();
?>

注意:PHP 7.2 前需 --with-libzip,且僅支援 ZipCrypto(弱)。AES-256 需較新 libzip。

流式壓縮:大文件/低記憶體場景

ZipArchive 需將整個壓縮包寫入磁盤再輸出,大文件佔用磁盤 IO。使用 maennchen/zipstream-php 直接輸出到 HTTP 響應流:

<?php
require 'vendor/autoload.php';

use ZipStream\ZipStream;

$zip = new ZipStream('large-export.zip', [
    'content_type' => 'application/zip',
    'enable_zip64' => true,
]);

// 動態添加大文件(如資料庫導出 CSV)
$zip->addFileFromPath('export-1.csv', '/data/exports/part1.csv');
$zip->addFileFromPath('export-2.csv', '/data/exports/part2.csv');
// ... 可持續添加,邊壓縮邊輸出

$zip->finish();
// 自動發送 Header 並輸出流,無需佔用伺服器磁盤空間
?>

高級庫:chumper/zipper (Laravel 風格)

<?php
require 'vendor/autoload.php';

use Chumper\Zipper\Zipper;

$zipper = new Zipper();
$zipper->make('backup.zip')
    ->add('uploads/')
    ->add('database.sql')
    ->close();

// 或鏈式
Zipper::make('backup.zip')->folder('app')->add('config/')->close();
?>

效能對比

方案100MB 文件壓縮記憶體峰值支援加密流式輸出
PHPZip (純 PHP)~120 秒~200MB否否
ZipArchive (C 擴展)~3 秒~10MBAES-256 (PHP 7.2+)否
ZipStream (流式)~3 秒~2MB否是

常見問題

問題原因解決
Class 'ZipArchive' not found未安裝 php-zip 擴展安裝 php-zip 或重新編譯 PHP
添加文件失敗路徑錯誤、權限不足、文件不存在用絕對路徑、檢查 is_readable()
中文文件名亂碼Zip 標準早期不支援 UTF-8PHP 8.0+ / libzip 1.7+ 自動處理,舊版需轉編碼
壓縮包超過 2GB/4GBZip64 支援ZipArchive::OVERWRITE | ZipArchive::CREATE (PHP 5.6+ 自動 Zip64)

總結

放棄純 PHP 的 PHPZip 類,首選內建 ZipArchive,功能完整、效能高、零依賴。大文件導出、低記憶體環境用 ZipStream 流式輸出。Laravel 專案可用 chumper/zipper 享受優雅 API。所有方案均基於 C 擴展,效能比純 PHP 快 1-2 個數量級。

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