/**
* @description: RAR读取,不支持创建
* 扩展安装地址:https://pecl.php.net/package/rar
*/
class RARCompress
{
/**
* @description: rar文件资源
* @var RarArchive
*/
protected $rar;
public function __construct($filename, $password = null)
{
// 发生错误时抛出异常而不是发出警告
RarException::setUsingExceptions(true);
$this->getRar($filename, $password);
}
public function __destruct()
{
$this->rar->close();
}
/**
* @description: 获取rar资源
* @param string $filename 文件路径
* @param string $password 文件密码
* @return {*}
*/
public function getRar($filename, $password = null)
{
$this->rar = RarArchive::open(realpath($filename), $password);
if ($this->rar) {
if ($this->rar->isBroken()) {
throw new \Exception('文件不完整(卷丢失或被截断)');
}
} else {
throw new \Exception('压缩包错误');
}
}
/**
* @description: 获取压缩包中指定路径的条目对象
* @param string $path 压缩包中的路径
* @return {*}
*/
public function getOne($path)
{
try {
$entry = $this->rar->getEntry($path);
return $this->entryAttribute($entry);
} catch (RarException $e) {
throw new \Exception('条目不存在');
}
}
/**
* @description: 解压缩文件,压缩包中的多层目录会自动处理
* @param string $dir 解压缩路径,默认当前目录;绝对路径相对路径都可以,
* 路径中的目录不存在时将自动创建,路径中不要带中文
* 压缩包中的中文不会乱码
* @return {*}
*/
public function uncompress($dir = '')
{
// 获取压缩包中所有条目对象
foreach($this->rar->getEntries() as $entry) {
// 解压到指定目录,true表示设置诸如NTFS ACL和Unix所有者信息之类的扩展信息,只要它们存在
$entry->extract($dir, '', null, true);
}
}
/**
* @description: 压缩条目属性
* @param RarEntry $entry 压缩条目
* @return {*}
*/
protected function entryAttribute($entry)
{
$is_dir = (bool)(
// 获取存档条目的主机操作系统的代码 获取档案条目的OS相关属性
((($entry->getHostOs() == RAR_HOST_WIN32) && ($entry->getAttr() & 0x10)) || // 支持Windows
(($entry->getHostOs() == RAR_HOST_UNIX) && (($entry->getAttr() & 0xf000) == 0x4000))) // 支持Unix
);
$name = $entry->getName();
if ($is_dir && $entry->isDirectory()) {
$dir = $name;
$file = '';
} else {
$names = explode('\\', $name);
$file = array_pop($names);
$dir = $names ? implode('/', $names) : '/';
}
return [
'is_dir' => $is_dir,
'dir' => $dir,
'name' => $file,
'packed_size' => $entry->getPackedSize(), // 压缩大小
'unpacked_size' => $entry->getUnpackedSize(), // 解压缩后的大小
'last_time' => $entry->getFileTime(), // 文件最后修改时间
];
}
/**
* @description: 异常转换
* @param int $code 异常编码
* @return {*}
*/
protected function exceptionCode($code)
{
return [
-1 => 'UnRAR 库之外的错误',
11 => '内存不足',
12 => '错误数据',
13 => '存档错误',
14 => '未知格式',
15 => '文件打开错误',
16 => '文件创建错误',
17 => '文件关闭错误',
18 => '读取错误',
19 => '写入错误',
20 => '缓冲区太小',
21 => '未知的 RAR 错误',
22 => '需要密码但未提供'
][$code] ?? '';
}
}