1. 程式人生 > >使用PHP壓縮檔案和解壓檔案 (ZipArchive類的使用)

使用PHP壓縮檔案和解壓檔案 (ZipArchive類的使用)

因為自己需要PHP來壓縮和解壓檔案,就上網查了一下發現沒有合適的,我就自己研究了一下PHP手冊中的ZipArchive類,在這裡記錄一下學到的東西。

1.ZipArchive類

首先來看看ZipArchive類的使用方法,這裡我翻譯了一下PHP手冊中的函式說明:

函式 功能
open 開啟一個zip檔案
close 關閉zip檔案(檔案是開啟的或新建的)
addEmptyDir 新增一個新的目錄
addFile 新增一個檔案
addFromString 使用檔案內容新增檔案
addGlob 使用glob模式新增檔案
addPattern 使用PCRE模式新增檔案
deleteIndex 使用索引刪除一個檔案或目錄
deleteName 使用名稱刪除一個檔案或目錄
extractTo 解壓Zip檔案
getArchiveComment 返回Zip檔案的說明
getCommentIndex 使用索引返回一個檔案或目錄的說明
getCommentName 使用名稱返回一個檔案或目錄的說明
getExternalAttributesIndex 使用索引檢索一個檔案或目錄的外部屬性
getExternalAttributesName 使用名稱檢索一個檔案或目錄的外部屬性
getFromIndex 使用索引返回檔案的內容
getFromName 使用檔名稱返回檔案的內容
getNameIndex 使用索引返回一個檔案或目錄的名稱
getStatusString 返回錯誤狀態訊息
getStream 得到一個檔案處理程式中的檔案或目錄名稱(只讀)。
locateName 返回檔案或目錄的索引
renameIndex 通過索引重新命名一個檔案或目錄
renameName 通過檔名重新命名一個檔案或目錄
setArchiveComment 設定ZIP歸檔的說明
setCommentIndex 通過索引設定一個檔案或目錄的說明
setCommentName 通過檔名設定一個檔案或目錄的說明
setCompressionIndex 通過索引設定一個檔案或目錄的壓縮方法
setCompressionName 通過檔名設定一個檔案或目錄的壓縮方法
setEncryptionIndex 通過索引設定一個檔案或目錄的加密方法
setEncryptionName 通過檔名設定一個檔案或目錄的加密方法
setExternalAttributesIndex 通過索引設定一個條目的外部屬性
setExternalAttributesName 通過檔名設定一個條目的外部屬性
setPassword 為ZIP檔案設定密碼
statIndex 通過索引得到一個檔案或目錄的詳細資訊
statName 通過檔名得到一個檔案或目錄的詳細資訊
unchangeAll 撤銷所有更改
unchangeArchive 恢復所有更改
unchangeIndex 通過索引恢復一個檔案或目錄的所有更改
unchangeName 通過檔名恢復一個檔案或目錄的所有更改

還有 ZipArchive類的公有屬性:

屬性 說明
status ZipArchive 的狀態
statusSys ZipArchive 的系統狀態
numFiles 壓縮包裡的檔案數
filename 在檔案系統裡的檔名
comment 壓縮包的說明



看到有這麼多函式是不是有些眼花?別怕,實現我們功能所使用的函式並不多。

2.使用ZipArchive壓縮檔案

壓縮檔案的步驟:
1. new一個ZipArchive類,並且新建一個ZIP檔案
2. 向ZIP檔案中新增檔案或目錄
3. 關閉ZIP檔案

第一步,新建ZIP檔案:

這步很簡單:

$zipArc = new ZipArchive();
$zipArc->open('file.zip', ZipArchive::CREATE);

第二步,向ZIP檔案中新增檔案或目錄:

從上面的函式列表中有幾個函式可以新增檔案或目錄:

函式 功能
addEmptyDir 新增一個新的目錄
addFile 新增一個檔案
addFromString 使用檔案內容新增檔案
addGlob 使用glob模式從一個目錄新增檔案
addPattern 使用PCRE模式從一個目錄新增檔案

向ZIP檔案新增一個空目錄:

$zipArc->addEmptyDir ('newdir', ZipArchive::CREATE);

向ZIP檔案新增一個檔案:

$zipArc->addFile ('file1.txt');

使用檔案內容向ZIP檔案新增一個檔案(意思就是把一段字串儲存到一個檔案,並且把這個檔案新增到ZIP檔案中):

$zipArc->addFromString ('output.txt', 'hello world!');

上面的函式都只能新增一個檔案或者目錄,如果想批量新增內容怎麼辦呢?別急,addGlob()addPattern()提供了我們需要的功能:

addGlobal()函式

bool ZipArchive::addGlob ( string $pattern [, int $flags = 0 [, array $options = array() ]] )

它使用glob模式向ZIP檔案中新增檔案,什麼是glob模式呢?不懂請戳這裡, 其實就是與linux命令中檔案匹配一樣的語法。

$zipArc->addGlob('class/*.php', 0, array('add_path' => 'phpclass/', 'remove_path' => 'class'))

這段程式碼把class目錄中字尾為'.php'的檔案新增到了ZIP檔案中phpclass目錄中。

addPattern()函式

bool ZipArchive::addPattern ( string $pattern [, string $path = "." [, array $options = array() ]] )

它使用PCRE模式向ZIP檔案中新增檔案,什麼是PCRE模式呢?不懂請戳這裡, 其實就是pcre正則表示式。

$zipArc->addPattern('/\.(?:php)$/', 'class', array('add_path' => 'phpclass/', 'remove_path' => 'class'))

這段程式碼功能也是把class目錄中字尾為'.php'的檔案新增到了ZIP檔案中phpclass目錄中。

有了這些,我們就可以寫一個檔案壓縮函數了:

/**
 * 使用ZIP壓縮檔案或目錄
 * @param  [string] $toName   壓縮後的檔名
 * @param  [string] $fromName 被壓縮的檔案或目錄名
 * @return [bool]             成功返回TRUE, 失敗返回FALSE
 */
function zip($fromName, $toName)
{
    if(!file_exists($fromName)){
        return FALSE;
    }
    $zipArc = new ZipArchive();
    if(!$zipArc->open($toName, ZipArchive::CREATE)){
        return FALSE;
    }
    $res = is_dir($fromName) ? $zipArc->addGlob("{$fromName}/*") : $zipArc->addFile($fromName);
    if(!$res){
        $zipArc->close();
        return FALSE;
    }
    return $zipArc->close();
}

測試程式碼:

if(zip('class', 'class.zip')){
    echo "success";
}
else{
    echo "failed";
}

這段程式碼就可以吧class目錄壓縮到class.zip檔案了,是不是很好用呢,大家可以複製這個函式直接使用。

3.使用ZipArchive壓縮檔案

壓縮檔案的步驟:
1. 新建ZipArchive類,並且開啟一個ZIP檔案
2. 解壓ZIP檔案中的檔案
3. 關閉ZIP檔案

解壓檔案就簡單多了:

$zipArc = new ZipArchive();
$zipArc->open('file.zip');
$zipArc->extractTo('dir');

上面的程式碼將會吧file.zip檔案解壓到dir目錄下(不存在會自動建立)。

我這裡也封裝成函式給大家使用:

/**
 * 解壓一個ZIP檔案
 * @param  [string] $toName   解壓到哪個目錄下
 * @param  [string] $fromName 被解壓的檔名
 * @return [bool]             成功返回TRUE, 失敗返回FALSE
 */
function unzip($fromName, $toName)
{
    echo filesize($fromName);
    if(!file_exists($fromName)){
        return FALSE;
    }
    $zipArc = new ZipArchive();
    if(!$zipArc->open($fromName)){
        return FALSE;
    }
    if(!$zipArc->extractTo($toName)){
        $zipArc->close();
        return FALSE;
    }
    return $zipArc->close();
}

測試程式碼:

if(unzip('class.zip', 'dir')){
    echo "success";
}
else{
    echo "failed";
}

上面的程式碼將會吧class.zip檔案解壓到dir目錄下(不存在會自動建立)。