在PHP开发中,处理RAR文件是一个常见的需求。RAR文件格式通常用于压缩和归档文件,而PHP提供了各种库和工具,使得操作RAR文件变得更加便捷和灵活。让我们一起探讨如何在PHP中处理RAR文件,实现文件的压缩、解压缩以及其他操作。
一、安装
Rar 目前可通过 PECL ” https://pecl.php.net/package/rar 获取。也可以使用 PECL 安装程序来安装 Rar 扩展,命令如下:
Pecl -v install rar
也可以下载 tar.gz 包,然后手动安装 Rar:
gunzip rar-xxx.tgz tar -xvf rar-xxx.tar cd rar-xxx phpize ./configure && make && make install
Windows 用户需要在 php.ini 中启用 php_rar.dll,才能使用这些功能。
二、预定义常量
下列常量由此扩展定义,且仅在此扩展编译入 PHP 或在运行时动态载入时可用。
- RAR_HOST_MSDOS (int):使用 RarEntry::HOST_MSDOS 代替。
- RAR_HOST_OS2 (int):使用 RarEntry::HOST_OS2 代替。
- RAR_HOST_WIN32 (int):使用 RarEntry::HOST_WIN32 代替。
- RAR_HOST_UNIX (int):使用 RarEntry::HOST_UNIX 代替。
- RAR_HOST_BEOS (int):使用 RarEntry::HOST_BEOS 代替。
三、示例
即时解压缩:
<?php if (!array_key_exists("i", $_GET) || !is_numeric($_GET["i"])) die("Index unspecified or non-numeric"); $index = (int) $_GET["i"]; $arch = RarArchive::open("example.rar"); if ($arch === FALSE) die("Cannot open example.rar"); $entries = $arch->getEntries(); if ($entries === FALSE) die("Cannot retrieve entries"); if (!array_key_exists($index, $entries)) die("No such index: $index"); $orfilename = $entries[$index]->getName(); //UTF-8 encoded $filesize = $entries[$index]->getUnpackedSize(); /* you could check HTTP_IF_MODIFIED_SINCE here and compare with * $entries[$index]->getFileTime(). You could also send a * "Last modified" header */ $fp = $entries[$index]->getStream(); if ($fp === FALSE) die("Cannot open file with index $index insided the archive."); $arch->close(); //no longer needed; stream is independent function detectUserAgent() { if (!array_key_exists('HTTP_USER_AGENT', $_SERVER)) return "Other"; $uas = $_SERVER['HTTP_USER_AGENT']; if (preg_match("@Opera/@", $uas)) return "Opera"; if (preg_match("@Firefox/@", $uas)) return "Firefox"; if (preg_match("@Chrome/@", $uas)) return "Chrome"; if (preg_match("@MSIE ([0-9.]+);@", $uas, $matches)) { if (((float)$matches[1]) >= 7.0) return "IE"; } return "Other"; } /* * We have 3 options: * - For FF and Opera, which support RFC 2231, use that format. * - For IE and Chrome, use attwithfnrawpctenclong * (http://greenbytes.de/tech/tc2231/#attwithfnrawpctenclong) * - For the others, convert to ISO-8859-1, if possible */ $formatRFC2231 = 'Content-Disposition: attachment; filename*=UTF-8\'\'%s'; $formatDef = 'Content-Disposition: attachment; filename="%s"'; switch (detectUserAgent()) { case "Opera": case "Firefox": $orfilename = rawurlencode($orfilename); $format = $formatRFC2231; break; case "IE": case "Chrome": $orfilename = rawurlencode($orfilename); $format = $formatDef; break; default: if (function_exists('iconv')) $orfilename = @iconv("UTF-8", "ISO-8859-1//TRANSLIT", $orfilename); $format = $formatDef; } header(sprintf($format, $orfilename)); //cannot send error messages from now on (headers already sent) //replace by real content type, perhaps infering from the file extension $contentType = "application/octet-stream"; header("Content-Type: $contentType"); header("Content-Transfer-Encoding: binary"); header("Content-Length: $filesize"); if ($_SERVER['REQUEST_METHOD'] == "HEAD") die(); while (!feof($fp)) { $s = @fread($fp, 8192); if ($s === false) break; //useless to send error messages echo $s; } ?>
本示例打开一个 RAR 文件,并显示 RAR 存档中的请求文件,供客户端下载:
<?php $rar_file = rar_open('example.rar') or die("Can't open Rar archive"); $entries = rar_list($rar_file); foreach ($entries as $entry) { echo 'Filename: ' . $entry->getName() . "\n"; echo 'Packed size: ' . $entry->getPackedSize() . "\n"; echo 'Unpacked size: ' . $entry->getUnpackedSize() . "\n"; $entry->extract('/dir/extract/to/'); } rar_close($rar_file); ?>
以上示例打开一个 RAR 文件存档,并将每个条目解压缩到指定目录。
四、Rar函数
rar_wrapper_cache_stats : URL 封装器的缓存命中率和未命中率。
rar_wrapper_cache_stats(): string
五、RarArchive类
此类表示一个 RAR 存档,它可能由多个卷(部分)组成,其中包含 许多 RAR 条目(即文件、目录和其他特殊对象,如符号链接)。
可以遍历此类的对象,从而生成存储在相应 RAR 存档中的条目。 这些条目也可以通过 RarArchive::getEntry() 和 RarArchive::getEntries() 获取。
1、类摘要
final class RarArchive implements Traversable { /* 方法 */ public close(): bool public getComment(): string public getEntries(): array|false public getEntry(string $entryname): RarEntry|false public isBroken(): bool public isSolid(): bool public static open(string $filename, string $password = NULL, callable $volume_callback = NULL): RarArchive|false public setAllowBroken(bool $allow_broken): bool public __toString(): string }
2、RarArchive函数
- RarArchive::close — 关闭 RAR 存档并释放所有资源;
- RarArchive::getComment — 从 RAR 存档中获取注释文本;
- RarArchive::getEntries — 从 RAR 存档中获取条目的完整列表;
- RarArchive::getEntry — 从 RAR 存档中获取条目对象;
- RarArchive::isBroken — 测试存档是否损坏(不完整);
- RarArchive::isSolid — 检查 RAR 存档是否可靠;
- RarArchive::open — 打开 RAR 存档;
- RarArchive::setAllowBroken — 是否允许打开损坏的存档;
- RarArchive::__toString — 获取文本表示。
六、RarEntry类
一个 RAR 条目,代表 RAR 存档中的一个目录或一个压缩文件。
1、类摘要
final class RarEntry { /* 常量 */ const int = 0HOST_MSDOS; const int = 1HOST_OS2; const int = 2HOST_WIN32; const int = 3HOST_UNIX; const int = 4HOST_MACOS; const int = 5HOST_BEOS; const int = 1ATTRIBUTE_WIN_READONLY; const int = 2ATTRIBUTE_WIN_HIDDEN; const int = 4ATTRIBUTE_WIN_SYSTEM; const int = 16ATTRIBUTE_WIN_DIRECTORY; const int = 32ATTRIBUTE_WIN_ARCHIVE; const int = 64ATTRIBUTE_WIN_DEVICE; const int = 128ATTRIBUTE_WIN_NORMAL; const int = 256ATTRIBUTE_WIN_TEMPORARY; const int = 512ATTRIBUTE_WIN_SPARSE_FILE; const int = 1024ATTRIBUTE_WIN_REPARSE_POINT; const int = 2048ATTRIBUTE_WIN_COMPRESSED; const int = 4096ATTRIBUTE_WIN_OFFLINE; const int = 8192ATTRIBUTE_WIN_NOT_CONTENT_INDEXED; const int = 16384ATTRIBUTE_WIN_ENCRYPTED; const int = 65536ATTRIBUTE_WIN_VIRTUAL; const int = 1ATTRIBUTE_UNIX_WORLD_EXECUTE; const int = 2ATTRIBUTE_UNIX_WORLD_WRITE; const int = 4ATTRIBUTE_UNIX_WORLD_READ; const int = 8ATTRIBUTE_UNIX_GROUP_EXECUTE; const int = 16ATTRIBUTE_UNIX_GROUP_WRITE; const int = 32ATTRIBUTE_UNIX_GROUP_READ; const int = 64ATTRIBUTE_UNIX_OWNER_EXECUTE; const int = 128ATTRIBUTE_UNIX_OWNER_WRITE; const int = 256ATTRIBUTE_UNIX_OWNER_READ; const int = 512ATTRIBUTE_UNIX_STICKY; const int = 1024ATTRIBUTE_UNIX_SETGID; const int = 2048ATTRIBUTE_UNIX_SETUID; const int = 61440ATTRIBUTE_UNIX_FINAL_QUARTET; const int = 4096ATTRIBUTE_UNIX_FIFO; const int = 8192ATTRIBUTE_UNIX_CHAR_DEV; const int = 16384ATTRIBUTE_UNIX_DIRECTORY; const int = 24576ATTRIBUTE_UNIX_BLOCK_DEV; const int = 32768ATTRIBUTE_UNIX_REGULAR_FILE; const int = 40960ATTRIBUTE_UNIX_SYM_LINK; const int = 49152ATTRIBUTE_UNIX_SOCKET; /* 方法 */ public extract( string $dir, string $filepath = "", string $password = NULL, bool $extended_data = false ): bool public getAttr(): int public getCrc(): string public getFileTime(): string public getHostOs(): int public getMethod(): int public getName(): string public getPackedSize(): int public getStream(string $password = ?): resource|false public getUnpackedSize(): int public getVersion(): int public isDirectory(): bool public isEncrypted(): bool public __toString(): string }
2、预定义常量
- RarEntry::HOST_MSDOS:如果 RarEntry::getHostOs() 的返回值等于此常数,则表示使用 MS-DOS 添加此条目。使用该常量代替 RAR_HOST_MSDOS。
- RarEntry::HOST_OS2:如果 RarEntry::getHostOs() 的返回值等于此常数,则表示使用 OS/2 添加此条目。旨在取代 RAR_HOST_OS2。
- RarEntry::HOST_WIN32:如果 RarEntry::getHostOs() 的返回值等于此常数,则使用 Microsoft Windows 添加此条目。旨在取代 RAR_HOST_WIN32。
- RarEntry::HOST_UNIX:如果 RarEntry::getHostOs() 的返回值等于此常量,则表示使用了未指定的 UNIX 操作系统添加此条目。用于替换 RAR_HOST_UNIX。
- RarEntry::HOST_MACOS:如果 RarEntry::getHostOs() 的返回值等于此常量,则表示使用 Mac OS 添加此条目。
- RarEntry::HOST_BEOS:如果 RarEntry::getHostOs() 的返回值等于此常数,则使用 BeOS 添加此条目。用于替换 RAR_HOST_BEOS。
- RarEntry::ATTRIBUTE_WIN_READONLY:表示具有只读属性的 Windows 条目的位。与 RarEntry::getAttr() 一起用于主机操作系统为 Microsoft Windows 的条目。
- RarEntry::ATTRIBUTE_WIN_HIDDEN:表示具有隐藏属性的 Windows 条目的位。与 RarEntry::getAttr() 一起用于主机操作系统为 Microsoft Windows 的条目。
- RarEntry::ATTRIBUTE_WIN_SYSTEM:表示具有系统属性的 Windows 条目的位。与 RarEntry::getAttr() 一起用于主机操作系统为 Microsoft Windows 的条目。
- RarEntry::ATTRIBUTE_WIN_DIRECTORY:表示具有目录属性的 Windows 条目(条目是一个目录)。与 RarEntry::getAttr() 一起用于主机操作系统为 Microsoft Windows 的条目。另请参阅 RarEntry::isDirectory(),它也适用于未在 WinRAR 中添加的条目。
- RarEntry::ATTRIBUTE_WIN_ARCHIVE:表示带有归档属性的 Windows 条目。与 RarEntry::getAttr() 一起用于主机操作系统为 Microsoft Windows 的条目。
- RarEntry::ATTRIBUTE_WIN_DEVICE:表示具有设备属性的 Windows 条目的位。与 RarEntry::getAttr() 一起用于主机操作系统为 Microsoft Windows 的条目。
- RarEntry::ATTRIBUTE_WIN_NORMAL:表示具有普通文件属性的 Windows 条目(条目不是目录)。与 RarEntry::getAttr() 一起用于主机操作系统为 Microsoft Windows 的条目。另请参阅 RarEntry::isDirectory(),它也适用于未在 WinRAR 中添加的条目。
- RarEntry::ATTRIBUTE_WIN_TEMPORARY:表示具有临时属性的 Windows 条目的位。与 RarEntry::getAttr() 一起用于主机操作系统为 Microsoft Windows 的条目。
- RarEntry::ATTRIBUTE_WIN_SPARSE_FILE:表示具有稀疏文件属性(文件为 NTFS 稀疏文件)的 Windows 条目的位。与 RarEntry::getAttr() 一起用于主机操作系统为 Microsoft Windows 的条目。
- RarEntry::ATTRIBUTE_WIN_REPARSE_POINT:用于表示具有稀疏点属性的 Windows 条目(条目是 NTFS 稀疏点,例如目录结点或挂载文件系统)。与 RarEntry::getAttr() 一起用于主机操作系统为 Microsoft Windows 的条目。
- RarEntry::ATTRIBUTE_WIN_COMPRESSED:表示具有压缩属性的 Windows 条目的位(仅限 NTFS)。与 RarEntry::getAttr() 一起用于主机操作系统为 Microsoft Windows 的条目。
- RarEntry::ATTRIBUTE_WIN_OFFLINE:表示 Windows 条目具有脱机属性(条目脱机且不可访问)的位。与 RarEntry::getAttr() 一起用于主机操作系统为 Microsoft Windows 的条目。
- RarEntry::ATTRIBUTE_WIN_NOT_CONTENT_INDEXED:表示 Windows 条目具有非内容索引属性(条目将被索引)的位。与 RarEntry::getAttr() 一起用于主机操作系统为 Microsoft Windows 的条目。
- RarEntry::ATTRIBUTE_WIN_ENCRYPTED:表示具有加密属性的 Windows 条目的位(仅限 NTFS)。与 RarEntry::getAttr() 一起用于主机操作系统为 Microsoft Windows 的条目。
- RarEntry::ATTRIBUTE_WIN_VIRTUAL:表示具有虚拟属性的 Windows 条目的位。与 RarEntry::getAttr() 一起用于主机操作系统为 Microsoft Windows 的条目。
- RarEntry::ATTRIBUTE_UNIX_WORLD_EXECUTE:表示 UNIX 条目可在全球范围内执行的位。与 RarEntry::getAttr() 一起用于主机操作系统为 UNIX 的条目。
- RarEntry::ATTRIBUTE_UNIX_WORLD_WRITE:表示 UNIX 条目全球可写的位。与 RarEntry::getAttr() 一起用于主机操作系统为 UNIX 的条目。
- RarEntry::ATTRIBUTE_UNIX_WORLD_READ:表示 UNIX 条目全球可读的位。与 RarEntry::getAttr() 一起用于主机操作系统为 UNIX 的条目。
- RarEntry::ATTRIBUTE_UNIX_GROUP_EXECUTE:表示 UNIX 条目可分组执行的位。与 RarEntry::getAttr() 一起用于主机操作系统为 UNIX 的条目。
- RarEntry::ATTRIBUTE_UNIX_GROUP_WRITE:表示 UNIX 条目可分组写入的位。与 RarEntry::getAttr() 一起用于主机操作系统为 UNIX 的条目。
- RarEntry::ATTRIBUTE_UNIX_GROUP_READ:表示 UNIX 条目组可读的位。与 RarEntry::getAttr() 一起用于主机操作系统为 UNIX 的条目。
- RarEntry::ATTRIBUTE_UNIX_OWNER_EXECUTE:表示 UNIX 条目是所有者可执行的位。与 RarEntry::getAttr() 一起用于主机操作系统为 UNIX 的条目。
- RarEntry::ATTRIBUTE_UNIX_OWNER_WRITE:表示 UNIX 条目所有者可写的位。与 RarEntry::getAttr() 一起用于主机操作系统为 UNIX 的条目。
- RarEntry::ATTRIBUTE_UNIX_OWNER_READ:表示 UNIX 条目所有者可读的位。与 RarEntry::getAttr() 一起用于主机操作系统为 UNIX 的条目。
- RarEntry::ATTRIBUTE_UNIX_STICKY:表示 UNIX 粘性位的位。与 RarEntry::getAttr() 一起用于主机操作系统为 UNIX 的条目。
- RarEntry::ATTRIBUTE_UNIX_SETGID:表示 UNIX setgid 属性的位。与 RarEntry::getAttr() 一起用于主机操作系统为 UNIX 的条目。
- RarEntry::ATTRIBUTE_UNIX_SETUID:表示 UNIX setuid 属性的位。与 RarEntry::getAttr() 一起用于主机操作系统为 UNIX 的条目。
- RarEntry::ATTRIBUTE_UNIX_FINAL_QUARTET:用于隔离 UNIX 属性(_S_IFMT,文件掩码类型)最后四位(nibble)的掩码。与 RarEntry::getAttr() 一起用于主机操作系统为 UNIX 的条目,并与常量 RarEntry::ATTRIBUTE_UNIX_FIFO、RarEntry::ATTRIBUTE_UNIX_CHAR_DEV、RarEntry::ATTRIBUTE_UNIX_CHAR_DEV 一起使用: ATTRIBUTE_UNIX_DIRECTORY、RarEntry::ATTRIBUTE_UNIX_BLOCK_DEV、RarEntry::ATTRIBUTE_UNIX_REGULAR_FILE、RarEntry::ATTRIBUTE_UNIX_SYM_LINK 和 RarEntry::ATTRIBUTE_UNIX_SOCKET。
- RarEntry::ATTRIBUTE_UNIX_FIFO:Unix FIFO 将具有最后四位具有此值的属性。与 RarEntry::getAttr() 一起用于主机操作系统为 UNIX 的条目,并与常量 RarEntry::ATTRIBUTE_UNIX_FINAL_QUARTET 一起使用。
- RarEntry::ATTRIBUTE_UNIX_CHAR_DEV:Unix 字符设备将具有最后四位具有此值的属性。与 RarEntry::getAttr() 一起用于主机操作系统为 UNIX 的条目,并与常量 RarEntry::ATTRIBUTE_UNIX_FINAL_QUARTET 一起使用。
- RarEntry::ATTRIBUTE_UNIX_DIRECTORYUnix 目录的属性的最后四位具有此值。与 RarEntry::getAttr() 一起用于主机操作系统为 UNIX 的条目,并与常量 RarEntry::ATTRIBUTE_UNIX_FINAL_QUARTET 一起使用。
- RarEntry::ATTRIBUTE_UNIX_BLOCK_DEV:Unix 块设备的属性最后四位具有此值。与 RarEntry::getAttr() 一起用于主机操作系统为 UNIX 的条目,并与常量 RarEntry::ATTRIBUTE_UNIX_FINAL_QUARTET 一起使用。
- RarEntry::ATTRIBUTE_UNIX_REGULAR_FILE:Unix 常规文件(非目录)的属性的最后四位具有此值。与 RarEntry::getAttr() 一起用于主机操作系统为 UNIX 的条目,并与常量 RarEntry::ATTRIBUTE_UNIX_FINAL_QUARTET 一起使用。另请参阅 RarEntry::isDirectory(),它也适用于在其他操作系统中添加的条目。
- RarEntry::ATTRIBUTE_UNIX_SYM_LINK:Unix 符号链接的属性后四位具有此值。与 RarEntry::getAttr() 一起用于主机操作系统为 UNIX 的条目,并与常量 RarEntry::ATTRIBUTE_UNIX_FINAL_QUARTET 一起使用。
- RarEntry::ATTRIBUTE_UNIX_SOCKET:Unix 套接字的最后四位属性值为此值。与 RarEntry::getAttr() 一起用于主机操作系统为 UNIX 的条目,并与常量 RarEntry::ATTRIBUTE_UNIX_FINAL_QUARTET 一起使用。
3、RarEntry函数
- RarEntry::extract – 从压缩包中提取条目。
- RarEntry::getAttr – 获取条目的属性。
- RarEntry::getCrc – 获取条目的 CRC。
- RarEntry::getFileTime – 获取条目的最后修改时间。
- RarEntry::getHostOs – 获取条目主机操作系统。
- RarEntry::getMethod – 获取条目的打包方法。
- RarEntry::getName – 获取条目的名称。
- RarEntry::getPackedSize – 获取条目的打包大小。
- RarEntry::getStream – 获取条目的文件处理程序。
- RarEntry::getUnpackedSize – 获取未打包条目的大小。
- RarEntry::getVersion – 获取解压缩条目所需的最小 RAR 程序版本。
- RarEntry::isDirectory – 测试条目是否代表一个目录。
- RarEntry::isEncrypted – 测试条目是否加密。
- RarEntry::__toString – 获取条目的文本表示形式。
七、RarException类
此类有两个用途:它是 RAR 扩展引发的异常类型 函数和方法,它允许通过静态方法查询和定义错误 扩展的行为,即是抛出异常还是仅发出警告。
使用以下错误代码:
- 1 – UnRAR 库外部的错误
- 11 – 内存不足
- 12 – 数据错误
- 13 – 错误的存档
- 14 – 未知格式
- 15 – 文件打开错误
- 16 – 文件创建错误
- 17 – 文件关闭错误
- 18 – 读取错误
- 19 – 写入错误
- 20 – 缓冲区太小
- 21 – 未知 RAR 错误
- 22 – 需要密码但未提供密码
1、类摘要
final class RarException extends Exception { /* 方法 */ public static isUsingExceptions(): bool public static setUsingExceptions(bool $using_exceptions): void /* 继承的方法 */ final public Exception::getMessage(): string final public Exception::getPrevious(): ?Throwable final public Exception::getCode(): int final public Exception::getFile(): string final public Exception::getLine(): int final public Exception::getTrace(): array final public Exception::getTraceAsString(): string public Exception::__toString(): string private Exception::__clone(): void }
2、RarException函数
- RarException::isUsingExceptions — 检查是否正在使用带有异常的错误处理。
- RarException::setUsingExceptions — 激活和停用异常错误处理。