PHP的zip壓縮工具擴展包學習

總算到了 PHP 的拿手好戲上場了,前面咱們學習過 Bzip2 、 LZF 、 Phar 和 rar 這些壓縮相關擴展在 PHP 中的使用,不過它們要麼是太冷門,要麼就是不少功能不支持。而 Zip 則是在 PHP 中獲得最大幅度功能支持的熱門壓縮格式,或者說是通用常見的一種壓縮格式。固然,也主要得益於 Zip 也是事實上的 Linux 環境中的通用壓縮格式。php

安裝

對於 PHP 來講,Zip 擴展已經集成在了 PHP 的安裝包中,在 Configure 的時候能夠直接加上 --with-zip ,若是在安裝的時候沒有加上這個參數,咱們也能夠在源碼包的 ext/zip 下找到源碼,而後經過擴展安裝的方式進行安裝。git

建立一個壓縮包

$zip = new ZipArchive();
$filename = './test_zip.zip';

if($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE){
        exit('cannot open ' . $filename .'\n');
}

// 加入文字類型的文件
$zip->addFromString('testfile1.txt' . time(), "#1");
$zip->addFromString('testfile2.txt' . time(), "#2");

// 加入已存在的文件
$zip->addFile('rar.php', 'newrar.php');

echo $zip->numFiles, PHP_EOL; // 文件數量
echo $zip->status, PHP_EOL; // 壓縮包狀態
$zip->close();

// 使用操做系統的 unzip 查看
// # unzip -l test_zip.zip
// Archive:  test_zip.zip
//   Length      Date    Time    Name
// ---------  ---------- -----   ----
//         2  07-08-2020 08:57   testfile1.txt1594169845
//         2  07-08-2020 08:57   testfile2.txt1594169845
//      2178  07-07-2020 08:55   newrar2.php
// ---------                     -------
//      2182                     3 files

以前學習過的 rar 擴展是沒法打包文件或者建立新的壓縮包的,而 Zip 一上來咱們就學習的是建立一個新的壓縮包。經過實例化一個 ZipArchive 對象後,咱們就可使用 open() 函數打開或建立一個壓縮包文件。接着,咱們使用了兩種添加內容的方式。addFromString() 是加入文字類型的文件,也就是將一段文字轉換成文本文件保存在這個壓縮包中。另外,咱們經過 addFile() 來將外部的文件加入到這個壓縮包中。github

numFiles 和 status 屬性能夠分別查看到壓縮包文件裏面的文件數量及當前這個壓縮包的狀態信息。最後直接使用 close() 關閉句柄便可。這樣,一個簡單的 Zip 壓縮包文件就建立完成了。咱們能夠直接使用操做系統的 unzip 命令來查看壓縮包的內容。函數

讀取壓縮包內容及信息

$zip = new ZipArchive();
$zip->open('./test_zip.zip');
print_r($zip); // 壓縮包信息
// ZipArchive Object
// (
//     [status] => 0
//     [statusSys] => 0
//     [numFiles] => 40
//     [filename] => /data/www/blog/test_zip.zip
//     [comment] =>
// )
var_dump($zip);
// object(ZipArchive)#2 (5) {
//     ["status"]=>
//     int(0)
//     ["statusSys"]=>
//     int(0)
//     ["numFiles"]=>
//     int(40)
//     ["filename"]=>
//     string(27) "/data/www/blog/test_zip.zip"
//     ["comment"]=>
//     string(0) ""
//   }

echo $zip->numFiles, PHP_EOL;
echo $zip->status, PHP_EOL;
echo $zip->statusSys, PHP_EOL;
echo $zip->filename, PHP_EOL;
echo $zip->comment, PHP_EOL;
echo $zip->count(), PHP_EOL;

for ($i=0; $i<$zip->numFiles;$i++) {
    echo "index: $i\n";
    // 打印每一個文件實體信息
    print_r($zip->statIndex($i));
    // index: 0
    // Array
    // (
    //     [name] => testfile1.txt1594169845
    //     [index] => 0
    //     [crc] => 2930664868
    //     [size] => 2
    //     [mtime] => 1594169844
    //     [comp_size] => 2
    //     [comp_method] => 0
    //     [encryption_method] => 0
    // )
    // ……

    $entry = $zip->statIndex($i);
    if($entry['name'] == 'newrar.php'){
        // 僅解壓 newrar.php 文件到指定目錄
        $zip->extractTo('./test_zip_single', $entry['name']);
    }
}

// 修改壓縮包內的文件名
$zip->renameName('newrar.php', 'newrar2.php');
print_r($zip->getFromIndex(2)); // 獲取第二個文件的內容
print_r($zip->getFromName('newrar2.php')); // 獲取指定文件名的文件內容

$zip->extractTo('./test_zip'); // 解壓整個壓縮包到指定目錄

$zip->close();

其實讀取也是一樣的步驟,實例化一個 ZipArchive 類,而後 open() 打開一個壓縮包文件句柄。接着就能夠直接輸出一些壓縮包的屬性信息。咱們能夠經過循環並經過 statIndex() 方法獲取每一個文件實體的信息。這裏須要注意的是 statIndex() 獲取的是文件的信息,而不是這個文件的內容。工具

固然,咱們也能夠經過 getFromIndex() 或 getFromName() 直接獲取指定的文件。經過 renameName() 直接給壓縮包內部的文件更名,經過 extractTo() 將指定的文件或者整個壓縮包解壓到指定的目錄中。extractTo() 方法的第二個參數若是指定了內容,則只會解壓指定的這個文件。學習

壓縮目錄,設置說明以及流、僞協議方式讀取文件

既然是壓縮包工具,那麼咱們最經常使用的也就是直接將多個文件或者目錄進行打包。同時,也有不少壓縮包能夠設置一些說明、密碼什麼的。另外,咱們還能夠經過專屬的 zip:// 僞協議來直接獲取壓縮包內某個文件的內容。這些功能,在 PHP 的 Zip 擴展中都可以很是簡單方便地使用。測試

壓縮目錄

// 壓縮目錄
$zip = new ZipArchive();
$zip->open('./test_zip2.zip', ZIPARCHIVE::CREATE);
$zip->addFile('rar.php', 'newrar.php');
$zip->addGlob('./test_zip/*.{php,txt}', GLOB_BRACE, ['add_path'=> 'new_path/']);

直接使用 addGlob 就能夠幫助咱們完成對某個文件目錄下的全部文件的內容打包。同時,它的第三個參數也能夠指定這些文件在壓縮包內部的路徑地址。操作系統

設置說明及密碼

// 設置註釋、密碼
$zip->setArchiveComment('This is rar Comment!');
$zip->setPassword('123');
$zip->close();

// 使用操做系統 unzip 查看
// # unzip -l test_zip2.zip
// Archive:  test_zip2.zip
// This is rar Comment!
//   Length      Date    Time    Name
// ---------  ---------- -----   ----
//      2178  07-07-2020 08:55   newrar.php
//      2178  07-08-2020 10:36   new_path/./test_zip/newrar.php
//      2178  07-08-2020 10:36   new_path/./test_zip/newrar2.php
// ---------                     -------
//      6534                     3 files

設置壓縮包的說明註釋以及密碼都是有現成的函數方法直接使用的。咱們再次經過操做系統的 unzip 命令,就能夠查看到這個壓縮包的註釋信息以及打包的目錄內容。原本測試的 test_zip/ 目錄下的內容被放在了 new_path/ 目錄下,這就是咱們自定的一個壓縮包內部的路徑地址。.net

流、僞協議方式讀取文件

// 流、僞協議方法讀取壓縮包內容
$zip = new ZipArchive();
$zip->open('./test_zip2.zip');

// 獲取文件流
$fp = $zip->getStream('newrar.php');
while(!feof($fp)){
   echo fread($fp, 2);
}
fclose($fp);

// 使用僞協議
$fp = fopen('zip://' . dirname(__FILE__) . '/test_zip2.zip#newrar.php', 'r');
while(!feof($fp)){
   echo fread($fp, 2);
}
fclose($fp);

// file_get_contents 使用僞協議
echo file_get_contents('zip://' . dirname(__FILE__) . '/test_zip2.zip#newrar.php');

// 直接使用僞協議將文件拷貝出來
copy('zip://' . dirname(__FILE__) . '/test_zip2.zip#newrar.php', './newrar2.php');

首先,咱們經過 getStream() 方法直接獲取壓縮包中某個文件的流,這種方式幾乎是全部壓縮類擴展都會提供的一種讀取文件的方式。而下面的方式則是經過 zip:// 僞協議直接使用 fopen() 、 file_get_contents() 函數來讀取壓縮包內部的某個文件。既然有了這麼方便的一個僞協議,那麼咱們要簡單的獲取並解壓某個文件也就變得十分容易了,直接使用 copy() 函數將這個文件拷貝出來就能夠了。code

總結

是否是感受比 rar 的操做強大了許多。都說了這是 PHP 主力支持的一種通用壓縮格式,因此固然功能會豐富許多,並且還有不少的函數方法咱們並無所有列出來,若是全列出來的話還不如你們本身去看手冊呢。這裏就是以一些簡單的例子讓你們看到這類擴展功能的操做,方便你們在業務選型的時候可以快速的聯想到咱們 PHP 就已經提供了這些現成的擴展。須要瞭解 Zip 其它內容的同窗能夠移步最下方的連接直接進入手冊中查閱。

測試代碼:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202007/source/PHP%E7%9A%84zip%E5%8E%8B%E7%BC%A9%E5%B7%A5%E5%85%B7%E6%89%A9%E5%B1%95%E5%8C%85%E5%AD%A6%E4%B9%A0.php

參考文檔:

https://www.php.net/manual/zh/book.zip.php

各自媒體平臺都可搜索【硬核項目經理】

相關文章
相關標籤/搜索