PHP中的ZIP壓縮與解壓

壓縮

ZipArchive::open第二個參數說明:

  • ZipArchive::OVERWRITE
    總是以一個新的壓縮包開始,此模式下如果已經存在則會被覆蓋。

  • ZipArchive::CREATE
    如果不存在則創建一個zip壓縮包。

  • ZipArchive::EXCL
    如果壓縮包已經存在,則出錯。

  • ZipArchive::CHECKCONS
    對壓縮包執行額外的一致性檢查,如果失敗則顯示錯誤。

壓縮單個文件

$zip = new ZipArchive();
$flag = $zip->open('C:/out.zip', ZipArchive::OVERWRITE);
if($flag!==true){
    echo "open error code: {$flag}\n";
    exit();
}
$zip->addFile('C:/1.txt', '1.txt'); //zip文件中的文件名爲1.txt,如果忽略,則會多一個名爲C:的文件夾
$flag = $zip->close();
echo $flag?'success':'fail';

壓縮多個文件

$zip = new ZipArchive();
$flag = $zip->open('C:/out.zip', ZipArchive::OVERWRITE);
if($flag!==true){
    echo "open error code: {$flag}\n";
    exit();
}
$zip->addFile('C:/1.txt', '1.txt');
$zip->addFile('C:/2.txt', '2.txt');
$flag = $zip->close();
echo $flag?'success':'fail';

添加文件到壓縮包

如果存在壓縮包,則添加;若不存在,則新建

$zip = new ZipArchive();
$flag = $zip->open('C:/out.zip', ZipArchive::CREATE);
if($flag!==true){
    echo "open error code: {$flag}\n";
    exit();
}
$zip->addFile('C:/2.txt', 'folder/2.txt');
$flag = $zip->close();
echo $flag?'success':'fail';

壓縮文件夾

/**
 * @param string $basePath         帶/結尾
 * @param string $relativePath     不帶/開頭
 * @param ZipArchive $zip
 */
function zipFolder($basePath, $relativePath, ZipArchive $zip)
{
    $handler = opendir($basePath.$relativePath);  //打開當前文件夾
    while(($filename = readdir($handler))!==false){
        if($filename!='.' && $filename!='..'){
            if(is_dir($basePath.$relativePath.'/'.$filename))
                zipFolder($basePath, $relativePath.'/'.$filename, $zip);
            else
                $zip->addFile($basePath.$relativePath.'/'.$filename, $relativePath.'/'.$filename);
        }
    }
    closedir($handler);
}

$zip = new ZipArchive();
$flag = $zip->open('C:/out.zip', ZipArchive::OVERWRITE);
if($flag!==true){
    echo "open error code: {$flag}\n";
    exit();
}
zipFolder('C:/', 'test', $zip);        //壓縮文件夾C:/test,並且壓縮包以test文件夾開始
$flag = $zip->close();
echo $flag?'success':'fail';

該程序有一個問題,如果包含一個空的子文件夾,則會被忽略,如果需要可以通過$zip->addEmptyDir('folder');補充

添加其它類型文件

addEmptyDir, addFromString

$zip = new ZipArchive();
$flag = $zip->open('C:/out.zip', ZipArchive::OVERWRITE);
if($flag!==true){
    echo "open error code: {$flag}\n";
    exit();
}
$zip->addFile('C:/1.txt', '1.txt');
$zip->addEmptyDir('folder1');       //添加一個空文件夾
$zip->addFromString('string.txt', 'hello everyone, my name is ...');    //添加字符串文件
$flag = $zip->close();
echo $flag?'success':'fail';

addGlob

$zip = new ZipArchive();
$flag = $zip->open('C:/out.zip', ZipArchive::OVERWRITE);
if($flag!==true){
    echo "open error code: {$flag}\n";
    exit();
}
$options = ['add_path'=>'ttt/', 'remove_all_path'=>true];   //移除所有路徑,並將路徑設置爲ttt
//添加符合通配符規則的文件
$zip->addGlob('C:/test/*.txt',0, $options);
$flag = $zip->close();
echo $flag?'success':'fail';

解壓

解壓整個文件

解壓文件到文件夾C:/out/中

$zip = new ZipArchive();
$flag = $zip->open('C:/in.zip');
if($flag!==true){
    echo "open error code: {$flag}\n";
    exit();
}
$zip->extractTo('C:/out/');
$flag = $zip->close();
echo $flag?'success':'fail';

注意:該程序不支持中文

支持中文的解壓縮

$zip = new ZipArchive();
$zipFilePath = 'C:/in.zip';
$flag = $zip->open($zipFilePath);
if($flag!==true){
    echo "open error code: {$flag}\n";
    exit();
}

$outDir = "C:/out/";
for($i=0;$i<$zip->numFiles;$i++){
    $statInfo = $zip->statIndex($i);
//    print_r($statInfo);
    if(substr($statInfo['name'], strlen($statInfo['name'])-1)=='/'){
        mkdir($outDir.substr($statInfo['name'], 0, -1));
    }
    else{
        copy('zip://'.$zipFilePath.'#'.$statInfo['name'], $outDir.'/'.$statInfo['name']);
    }
}

$flag = $zip->close();
echo $flag?'success':'fail';

提取壓縮包中指定的文件

使用上述例子中的$statInfo = $zip->statIndex($i);獲得的$statInfo['name']進行過濾。

讀取信息

$zip = new ZipArchive();
$zipFilePath = 'C:/in.zip';
$flag = $zip->open($zipFilePath);
if($flag!==true){
    echo "open error code: {$flag}\n";
    exit();
}

$outDir = "C:/out/";
for($i=0;$i<$zip->numFiles;$i++){
    $statInfo = $zip->statIndex($i);
    print_r($statInfo);
}

$flag = $zip->close();
echo $flag?'success':'fail';

備註

ZipArchive::open返回值

如果打開成功則返回true,否則返回錯誤碼,一下錯誤碼錶。

  • ZipArchive::ER_EXISTS
    文件已存在

  • ZipArchive::ER_INCONS
    zip archive前後不一致

  • ZipArchive::ER_INVAL
    參數不合法

  • ZipArchive::ER_MEMORY
    malloc失敗

  • ZipArchive::ER_NOENT
    沒有這個文件

  • ZipArchive::ER_NOZIP
    不是一個zip archive

  • ZipArchive::ER_OPEN
    無法打開文件

  • ZipArchive::ER_READ
    讀取失敗

  • ZipArchive::ER_SEEK
    seek失敗

參考

發佈了94 篇原創文章 · 獲贊 110 · 訪問量 80萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章