Rar and ZIP have been the terminator of compression in the field of computer. Rar format is the dominant existing in Windows system. The PHP extension we learn today is for rar compression package operation. However, THE RAR extension of PHP can only read and decompress RAR format, but cannot compress the package.

The phP-RAR extension in pecl is out of date and cannot be used in PHP7. We need to compile and install it using github source code to be able to install it successfully in PHP7.

Github.com/cataphract/…

Git Clone can be installed as a normal PHP extension.

Gets the compressed package handle 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)
Copy the code

The PHP-RAR extension can be written in two forms, one of which is object-oriented, using the RarArchive class to manipulate compressed packages. Another option is to use the rar_open function directly to get a rar file handle. They both override the __toString method, so we can just print the contents of the handle to see the actual file that the current handle operates on.

When we close the handle, the handle object can still output, but it is followed by a closed. The handle object can’t do anything else.

$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;
Copy the code

The RarArchive object has several methods that help us get information about the current compressed package. For example, getComment() gets the description of the package, isBroken() gets whether the current package isBroken, and isSolid() checks whether the current package is available. The setAllowBroken() method lets us allow the corrupted compression package to operate. Here we give object-oriented and procedural writing.

Compress each entity file or directory within the package to operate RarEntry

Once we have the handle to the compressed package, we need to further get the contents inside the compressed package. The handle object already holds the RarEntry object of each file and directory inside the compressed package.

$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
}
// Output the entire contents of the file
echo PHP_EOL;

echo 'Entry extract: '.$gameEntry->extract(". /"), PHP_EOL;

Copy the code

The getEntry() method of the handle object is used to get the contents of the specified file or directory. It fetches a single file or directory, so you must explicitly specify what file contents you want to fetch. With this method, we can get a RarEntry object. Next, some operations on this object.

The getName() method of the RarEntry object is used to get the name of the file with a path, which is the absolute path inside the compressed package. The getUnpackedSize() method is used to get the size of the file, and getStream() is used to get the stream. With getStream(), we can print out the contents of the file directly.

Of course, the most important thing is that we can extract a file directly to a specified directory using the extract() method. The php-RAR extension does not provide a way to completely unpack the entire package, so if we need to unpack the entire package, we need to unpack the files one by one by looping through the entire contents of the package.

Finally, we’ll look at how to traverse the entire contents of the compressed package.

$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;

}

// Compress the contents of all files in the package
// RarEntry for file "ldxlcs/ldxlcs/game.htm" (3c19abf6)
// ldxlcs/ldxlcs/game.htm
/ / 56063
/ / 32
// 3c19abf6
/ / the 2017-09-10 13:25:04
/ / 2
/ / 51
/ / 7049
/ / 200
/ /...

$entriesNo = rar_list($archNo);
foreach ($entriesNo as $en) {
    echo $en->getName(), PHP_EOL;
}
Copy the code

Using the getEntries() method of the RarArchive object, we get an array of RarEntry objects that contains the contents of the RAR package. In this code, we’ve also printed out some other property methods of the RarEntry object, which get all sorts of information about the file by name, so you can test them yourself.

Exception handling

Finally, the php-RAR extension will report PHP errors if you open the wrong file or get a file that is not in the compressed package. But since it provides a complete object-oriented writing, it must also provide a set of object-oriented exception handling mechanism.

// If UsingExceptions are not turned on, all errors will go to PHP error mechanism
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
    / /}
}
Copy the code

As long as RarException: : setUsingExceptions () is set to true, will be able to open the PHP – rar extension of exception handling mechanism, at this moment, we opened a wrong file, or to obtain an error within the zip file path, then, The error message is thrown as an exception.

conclusion

Does this extension feel human? Both object – oriented approach and procedure – oriented approach are provided. However, there is not much benefit to doing so, because the internal implementation of the extension itself is much more complex when it comes to juggling old code with new ideas. Try not to do this when we write our own code, and migrate to the latest form step by step during refactoring.

There is not much useful information about rar compression operation. Of course, if we want to generate compressed packages in the production environment, in most cases, we will directly generate zip format and provide it to users. After all, most client software can support decompression of rar and ZIP format files at the same time. If rar must be specified, You can also consult with product managers or customers. Sometimes, technical difficulties can be solved through business flexibility, but the most important thing is communication.

Test code:

Github.com/zhangyue050…

Reference Documents:www.php.net/manual/zh/b…

Follow the public account: [Hardcore project manager] to get the latest articles

Add WeChat/QQ friends: free xiaoyuezigonggong / 149844827 】 【 PHP, project management, learning materials

Zhihu, Public Account, Douyin, Toutiao Search [Hardcore Project Manager]

ID of station B: 482780532