使用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
目錄下(不存在會自動建立)。