作為壓縮解壓方面的擴(kuò)展學(xué)習(xí),兩大王牌壓縮格式 rar 和 zip 一直是計(jì)算機(jī)領(lǐng)域的壓縮終結(jié)者。rar 格式的壓縮包是 Windows 系統(tǒng)中有接近統(tǒng)治地位的存在,今天我們學(xué)習(xí)的 PHP 擴(kuò)展就是針對(duì)于 rar 的壓縮包操作,不過(guò),PHP 的 rar 擴(kuò)展僅能讀取和解壓 rar 格式的壓縮包,并不能進(jìn)行壓縮操作。
php-rar 擴(kuò)展在 pecl 的安裝包已經(jīng)過(guò)時(shí)了,無(wú)法在 PHP7 中使用,我們需要使用它在 github 上的源碼進(jìn)行編譯安裝才能夠在 PHP7 的環(huán)境下安裝成功。
https://github.com/cataphract/php-rar
直接 git clone 之后就可以按正常的 PHP 擴(kuò)展的方式進(jìn)行安裝。
獲取壓縮包句柄 RarArchive
$arch = RarArchive::open("test.rar");
$archNo = rar_open("test.rar");
echo $arch, PHP_EOL; // RAR Archive "/data/www/blog/test.rar"
echo $archNo, PHP_EOL; // RAR Archive "/data/www/blog/test.rar"
$arch->close();
rar_close($archNo);
echo $arch, PHP_EOL; // RAR Archive "/data/www/blog/test.rar" (closed)
echo $archNo, PHP_EOL; // RAR Archive "/data/www/blog/test.rar" (closed)
php-rar 擴(kuò)展有兩種形式的寫(xiě)法,一種是面向?qū)ο蟮?,也就是使?RarArchive 類(lèi)來(lái)操作壓縮包。另一種方式就是直接使用一個(gè)函數(shù) rar_open 用來(lái)獲取一個(gè) rar 文件的句柄。它們都重寫(xiě)了 __toString 方法,所以我們可以直接打印句柄的內(nèi)容看到當(dāng)前句柄所操作的具體文件。
當(dāng)我們關(guān)閉句柄時(shí),句柄對(duì)象依然能夠進(jìn)行輸出,但后面會(huì)顯示一個(gè) closed 。這時(shí)的句柄對(duì)象已經(jīng)不能進(jìn)行其它操作了。
$arch = RarArchive::open("test.rar");
$archNo = rar_open("test.rar");
echo $arch->getComment(), PHP_EOL;
echo $arch->isBroken(), PHP_EOL;
echo $arch->isSolid(), PHP_EOL;
echo rar_comment_get($archNo), PHP_EOL;
echo rar_broken_is($archNo), PHP_EOL;
echo rar_solid_is($archNo), PHP_EOL;
echo $arch->setAllowBroken(true), PHP_EOL;
echo rar_allow_broken_set($archNo, true), PHP_EOL;
RarArchive 對(duì)象的一些方法可以幫我們獲取當(dāng)前壓縮包的信息。比如 getComment() 獲取壓縮包的說(shuō)明信息,isBroken() 獲取當(dāng)前壓縮包是否有損壞,isSolid() 檢查當(dāng)前壓縮包是否可用。而 setAllowBroken() 方法是讓我們?cè)试S對(duì)損壞的壓縮包進(jìn)行操作。這里我們給出了面向?qū)ο蠛兔嫦蜻^(guò)程的寫(xiě)法。
壓縮包內(nèi)的每個(gè)實(shí)體文件或目錄操作 RarEntry
獲得壓縮包的句柄之后,我們就需要更進(jìn)一步地獲取壓縮包內(nèi)部的內(nèi)容。而句柄對(duì)象中就已經(jīng)保存了壓縮包內(nèi)部的各個(gè)文件和目錄的對(duì)象 RarEntry 。
$gameEntry = $arch->getEntry('ldxlcs/ldxlcs/game.htm');
echo $gameEntry->getName(), PHP_EOL; // ldxlcs/ldxlcs/game.htm
echo $gameEntry->getUnpackedSize(), PHP_EOL; // 56063
$gameEntryNo = rar_entry_get($arch, "ldxlcs/ldxlcs/game.htm");
echo $gameEntry->getName(), PHP_EOL; // ldxlcs/ldxlcs/game.htm
echo $gameEntry->getUnpackedSize(), PHP_EOL; // 56063
$fp = $gameEntryNo->getStream();
while (!feof($fp)) {
$buff = fread($fp, 8192);
if ($buff !== false) {
echo $buff;
} else {
break;
}
//fread error
}
// 輸出文件的全部?jī)?nèi)容
echo PHP_EOL;
echo 'Entry extract: ', $gameEntry->extract("./"), PHP_EOL;
句柄對(duì)象的 getEntry() 方法就是用于獲取指定的文件或者目錄內(nèi)容的。它獲取的是單個(gè)文件或目錄,所以必須明確地指定需要獲取的文件內(nèi)容。通過(guò)這個(gè)方法,我們可以拿到一個(gè) RarEntry 對(duì)象。接下來(lái),就是這個(gè)對(duì)象的一些操作。
RarEntry 對(duì)象的 getName() 方法用于獲取文件名稱,這個(gè)文件名稱是帶路徑的,這個(gè)路徑是壓縮包內(nèi)的絕對(duì)路徑。getUnpackedSize() 方法用于獲取文件的大小,getStream() 用于獲取文件流,通過(guò) getStream() 方法,我們就可以直接打印輸出文件的內(nèi)容。
當(dāng)然,最最重要的是,我們可以通過(guò) extract() 方法來(lái)直接解壓一個(gè)文件到指定的目錄。php-rar 擴(kuò)展并沒(méi)有提供一個(gè)能夠完全地解壓整個(gè)壓縮包的方法,所以如果我們需要對(duì)整個(gè)壓縮包進(jìn)行解壓的話,就需要通過(guò)循環(huán)遍歷壓縮包內(nèi)部的全部?jī)?nèi)容來(lái)對(duì)這些文件一個(gè)一個(gè)地進(jìn)行解壓。
最后,我們就來(lái)看看如何遍歷壓縮包內(nèi)的全部?jī)?nèi)容。
$entries = $arch->getEntries();
foreach ($entries as $en) {
echo $en, PHP_EOL;
echo $en->getName(), PHP_EOL;
echo $en->getUnpackedSize(), PHP_EOL;
echo $en->getAttr(), PHP_EOL;
echo $en->getCrc(), PHP_EOL;
echo $en->getFileTime(), PHP_EOL;
echo $en->getHostOs(), PHP_EOL;
echo $en->getMethod(), PHP_EOL;
echo $en->getPackedSize(), PHP_EOL;
echo $en->getVersion(), PHP_EOL;
echo $en->isDirectory(), PHP_EOL;
echo $en->isEncrypted(), PHP_EOL;
}
// 壓縮包中所有文件的內(nèi)容
// RarEntry for file "ldxlcs/ldxlcs/game.htm" (3c19abf6)
// ldxlcs/ldxlcs/game.htm
// 56063
// 32
// 3c19abf6
// 2017-09-10 13:25:04
// 2
// 51
// 7049
// 200
// ……
$entriesNo = rar_list($archNo);
foreach ($entriesNo as $en) {
echo $en->getName(), PHP_EOL;
}
直接使用的是 RarArchive 對(duì)象的 getEntries() 方法,我們通過(guò)這個(gè)方法可以獲得一個(gè) RarEntry 對(duì)象的數(shù)組,里面包含的就是這個(gè) rar 壓縮包里面的全部?jī)?nèi)容。在這段代碼中,我們還打印了 RarEntry 對(duì)象的其它一些屬性方法,根據(jù)名稱也能大概了解這些方法都是獲取關(guān)于文件的各種信息的,大家可以自行測(cè)試。
異常處理
最后,如果打開(kāi)錯(cuò)了文件或者獲取壓縮包內(nèi)部沒(méi)有的文件時(shí),php-rar 擴(kuò)展會(huì)以 PHP 錯(cuò)誤的形式報(bào)錯(cuò)。但既然提供了完整的面向?qū)ο髮?xiě)法,那么它也必然提供了一套面向?qū)ο蟮漠惓L幚頇C(jī)制。
// 不打開(kāi) UsingExceptions 全部錯(cuò)誤會(huì)走 PHP 錯(cuò)誤機(jī)制,打開(kāi)后走 PHP 的異常機(jī)制
RarException::setUsingExceptions(true);
var_dump(RarException::isUsingExceptions()); // bool(true)
try {
$arch = RarArchive::open("test1.rar");
$arch->getEntry('ttt.txt');
} catch (RarException $e) {
var_dump($e);
// object(RarException)#35 (7) {
// ["message":protected]=>
// string(91) "unRAR internal error: Failed to open /data/www/blog/test1.rar: ERAR_EOPEN (file open error)"
// ["string":"Exception":private]=>
// string(0) ""
// ["code":protected]=>
// int(15)
// ["file":protected]=>
// string(22) "/data/www/blog/rar.php"
// ["line":protected]=>
// int(93)
// ["trace":"Exception":private]=>
// array(1) {
// [0]=>
// array(6) {
// ["file"]=>
// string(22) "/data/www/blog/rar.php"
// ["line"]=>
// int(93)
// ["function"]=>
// string(4) "open"
// ["class"]=>
// string(10) "RarArchive"
// ["type"]=>
// string(2) "::"
// ["args"]=>
// array(1) {
// [0]=>
// string(9) "test1.rar"
// }
// }
// }
// ["previous":"Exception":private]=>
// NULL
// }
}
只要將 RarException::setUsingExceptions() 設(shè)置為 true ,就能夠開(kāi)啟 php-rar 擴(kuò)展的異常處理機(jī)制,這時(shí),我們打開(kāi)一個(gè)錯(cuò)誤的文件,或者去獲取壓縮包內(nèi)的一個(gè)錯(cuò)誤文件路徑,那么,錯(cuò)誤信息就會(huì)以異常的形式進(jìn)行拋出。
總結(jié)
這套擴(kuò)展是不是感覺(jué)很人性化?即提供了面向?qū)ο蟮姆绞?,也提供了以函?shù)操作為主的面向過(guò)程的方式。但是,這樣做其實(shí)并沒(méi)有太多的好處,因?yàn)橛忠骖櫪洗a,又要兼顧新思想,本身擴(kuò)展的內(nèi)部實(shí)現(xiàn)相必也會(huì)復(fù)雜很多。我們自己寫(xiě)代碼的時(shí)候就盡量不要這么寫(xiě)了,在重構(gòu)的時(shí)候一步步的向最新的形式遷移即可。
關(guān)于 rar 的壓縮操作并沒(méi)有找到太多有用的資料。當(dāng)然,我們?cè)谏a(chǎn)環(huán)境中如果要生成壓縮包的話大部分情況下都會(huì)直接去生成 zip 格式的提供給用戶,畢竟大部分的客戶端軟件都是能夠同時(shí)支持 rar 和 zip 格式文件的解壓的,如果一定要指定生成 rar 的話,也可以多多和產(chǎn)品經(jīng)理或者客戶商量。有的時(shí)候,技術(shù)的難點(diǎn)是可以通過(guò)業(yè)務(wù)的變通來(lái)解決的,最重要的其實(shí)還是在于溝通。
測(cè)試代碼:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202007/source/PHP%E7%9A%84rar%E8%A7%A3%E5%8E%8B%E8%AF%BB%E5%8F%96%E6%89%A9%E5%B1%95%E5%8C%85%E5%AD%A6%E4%B9%A0.php
參考文檔:
https://www.php.net/manual/zh/book.rar.php
以上就是PHP的rar解壓讀取擴(kuò)展包學(xué)習(xí)的詳細(xì)內(nèi)容,更多關(guān)于PHP rar解壓讀取的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
您可能感興趣的文章:- php解壓縮zip和rar壓縮包文件的方法
- php安裝php_rar擴(kuò)展實(shí)現(xiàn)rar文件讀取和解壓的方法
- php 解壓rar文件及zip文件的方法
- PHP執(zhí)行zip與rar解壓縮方法實(shí)現(xiàn)代碼
- ThinkPHP5.0框架驗(yàn)證碼功能實(shí)現(xiàn)方法【基于第三方擴(kuò)展包】