當前位置: 首頁> 最新文章列表> 如何使用PHP 的zip_read() 函數來詳細分析和讀取Zip 壓縮包的內部結構?

如何使用PHP 的zip_read() 函數來詳細分析和讀取Zip 壓縮包的內部結構?

M66 2025-06-23

在處理壓縮文件時,PHP 提供了強大的Zip 擴展來支持對.zip文件的讀取與操作。本文將深入講解zip_read()函數的用法,並配合其他相關函數,演示如何遍歷Zip 文件中的每一個條目並提取其中的內容或信息。

一、前提條件

在使用zip_read()前,需確保你的PHP 環境已啟用Zip 擴展。如果不確定,可使用如下代碼查看擴展是否已加載:

 <?php
if (class_exists('ZipArchive')) {
    echo "Zip 擴展已啟用";
} else {
    echo "Zip 擴展未啟用";
}
?>

如果返回結果是“Zip 擴展未啟用”,你需要在php.ini文件中啟用相關擴展,或在安裝PHP 時加入--with-zip選項。

二、zip_read() 的基本用法

zip_read()是配合zip_open()zip_entry_*系列函數使用的。它的作用是讀取打開的.zip文件中的一個條目。每次調用會返回一個下一個條目的資源句柄,直到返回false表示沒有更多的條目可讀。

三、示例代碼:逐項讀取Zip 文件中的條目

下面是一個完整的示例,展示如何打開一個.zip文件,遍歷其所有條目,並讀取每個條目的名稱與內容:

 <?php
$zipFile = '/path/to/example.zip'; // 替換為你本地的 zip 文件路徑
$zip = zip_open($zipFile);

if (is_resource($zip)) {
    while ($zip_entry = zip_read($zip)) {
        echo "<strong>文件名:</strong> " . zip_entry_name($zip_entry) . "<br>";

        if (zip_entry_open($zip, $zip_entry, "r")) {
            $contents = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
            echo "<strong>內容預覽:</strong><br><pre>" . htmlentities(substr($contents, 0, 500)) . "</pre><hr>";
            zip_entry_close($zip_entry);
        }
    }
    zip_close($zip);
} else {
    echo "無法打開壓縮文件。";
}
?>

四、核心函數講解

以下是與zip_read()搭配使用的關鍵函數:

  • zip_open(string $filename) :打開Zip 文件並返回資源句柄。

  • zip_read(resource $zip) :從Zip 文件資源中讀取下一個條目。

  • zip_entry_name(resource $entry) :獲取當前條目的文件名。

  • zip_entry_open(resource $zip, resource $entry, string $mode) :打開一個條目,準備讀取內容。

  • zip_entry_read(resource $entry, int $length) :讀取當前打開條目的內容。

  • zip_entry_close(resource $entry) :關閉打開的條目。

  • zip_close(resource $zip) :關閉Zip 文件資源。

五、實際應用:掃描上傳的Zip 文件內容

當你構建一個用戶可以上傳.zip文件的系統時,可能需要對上傳的文件內容進行掃描,比如過濾非法文件名、黑名單擴展名等。使用zip_read()可以實現逐項遍歷並篩查的功能。

例如:

 <?php
function scanZipForPhp($zipPath) {
    $zip = zip_open($zipPath);
    if (!is_resource($zip)) {
        return false;
    }

    $suspicious = [];

    while ($entry = zip_read($zip)) {
        $name = zip_entry_name($entry);
        if (preg_match('/\.php$/i', $name)) {
            $suspicious[] = $name;
        }
    }

    zip_close($zip);
    return $suspicious;
}

$flaggedFiles = scanZipForPhp('/tmp/uploaded.zip');
if (!empty($flaggedFiles)) {
    echo "發現可疑 PHP 文件:<br>";
    echo implode('<br>', $flaggedFiles);
} else {
    echo "未發現可疑文件。";
}
?>

六、注意事項

  1. zip_read()zip_entry_*系列函數是PHP 較早期提供的方法,適用於較為底層的Zip 操作。如果你需要更豐富的功能(如創建Zip 文件、添加註釋等),推薦使用ZipArchive類。

  2. 使用zip_read()無法直接訪問加密壓縮包中的內容。

  3. 若Zip 文件內容較大,應避免一次性讀取所有內容,防止內存溢出。

七、結語