簡體   English   中英

php ZipArchive檢查Zip文件是否已損壞/不完整

[英]php ZipArchive check if Zip file is broken/incomplete

我的用戶通過FTP上傳zip文件,然后php文件將它們添加到RSS文件中。

我正在嘗試找到一種方法來檢查每個ZIP文件以驗證文件,並檢查它是否已損壞或上傳是否未完成。 有沒有辦法做到這一點 ?

open的結果也可以是true應首先進行評估。 沒有檢查ZipArchive:ER_NOZIP ,等於(int)1,將始終匹配。

$zip = new ZipArchive();
$res = $zip->open('test.zip', ZipArchive::CHECKCONS);
if ($res !== TRUE) {
    switch($res) {
        case ZipArchive::ER_NOZIP:
            die('not a zip archive');
        case ZipArchive::ER_INCONS :
            die('consistency check failed');
        case ZipArchive::ER_CRC :
            die('checksum failed');
        default:
            die('error ' . $res);
    }
}

您可以使用ZipArchive類。 從PHP5.2開始,它是標准php發行版的一部分。

像這樣使用它:

$zip = new ZipArchive();

// ZipArchive::CHECKCONS will enforce additional consistency checks
$res = $zip->open('test.zip', ZipArchive::CHECKCONS);
switch($res) {

    case ZipArchive::ER_NOZIP :
        die('not a zip archive');
    case ZipArchive::ER_INCONS :
        die('consistency check failed');
    case ZipArchive::ER_CRC :
        die('checksum failed');

    // ... check for the other types of errors listed in the manual
}

如果zip存檔不完整或以其他方式損壞$zip->open()將返回ZipArchive::ER_NOZIP

如何檢測CRC不匹配的損壞文件:

ZipArchive似乎無法檢測到損壞的文件。 ZipArchive :: CHECKCONS沒有幫助,只有它根本不是ZIP文件。 它在我的測試中愉快地解壓縮了損壞的文件,並且不通知客戶端下載數據。

創建用於測試的損壞存檔很簡單 - 壓縮一些文件並在生成的ZIP文件中使用十六進制編輯器更改字節。 現在,您可以使用ZIP應用程序測試該文件,以了解存檔中的哪個文件已損壞。

您只需在服務器上驗證CRC以獲取較小的文件:

<?php
$maxsize = 1024*1024;
$z = new ZipArchive;
$r = $z->open("foo.zip", ZipArchive::CHECKCONS);
if($r !== TRUE)
  die('ZIP error when trying to open "foo.zip": '.$r);

$stat = $z->statName("mybrokenfile.txt");
if($stat['size'] > $maxsize)
  die('File too large, decompression denied');
$s = $z->getStream($file);
$data = stream_get_contents($s, $maxsize);
fclose($s);
if($stat['crc'] != crc32($data))
  die('File is corrupt!');
//echo 'File is valid';

//you may send the file to the client now if you didn't output anything before
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="mybrokenfile.txt"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . $stat['size']);
ob_clean();
echo $data;
$z->close();
?>

如果文件不能在服務器上完全解壓縮但由於其大小而在流式傳輸到客戶端時解壓縮,則文件傳輸已經啟動並且稍后打印錯誤消息不起作用。 也許最好的方法是在關閉文件傳輸之前中斷連接。 客戶端應該能夠將此檢測為損壞的下載。 在服務器端需要一個函數,它可以逐步計算流數據的CRC32。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM