kiwilan/php-archive

PHP 打包程序,用于处理存档文件(.zip, .rar, .tar, .7z, .pdf),具有统一的 API 和混合解决方案(本地/p7zip),旨在与 EPUB 和 CBA(.cbz, .cbr, .cb7, .cbt)协同工作。

2.3.0 2024-03-20 12:57 UTC

README

Banner with archives picture in background and PHP Archive title

php version downloads license tests codecov

PHP 打包程序,用于处理存档文件(.zip.rar.tar.7z.pdf),具有统一的 API 和混合解决方案(本地/p7zip),旨在与 EPUB 和 CBA(.cbz.cbr.cb7.cbt)协同工作。

支持 Linux、macOS 和 Windows。

警告

对于某些格式(.rar.7z),可能需要 rar PHP 扩展p7zip 二进制文件,请参阅要求

要求

  • PHP 版本 >= 8.1
  • PHP 扩展:
    • zip(本地,可选)用于 .ZIP.EPUB.CBZ 存档
    • fileinfo(本地,可选)用于更好的文件检测
    • rar(可选)用于 .RAR.CBR 存档
    • imagick(可选)用于 .PDF
    • bz2(可选)用于 .BZ2 存档

*:对于带密码的 .tar 存档,由于扩展不支持密码,将使用 .7z

注意

在此您可以阅读一些依赖项的安装指南

警告

  • 在 macOS 上,对于 .rar 提取,您必须 安装 rar 二进制文件 以提取文件,因为 p7zip 不支持 .rar 提取。
  • 在 Windows 上,对于 .pdf 提取,imagick PHP 扩展 必须工作,但 我的测试在该功能上失败了。因此,为了提取 PDF 页面,我建议使用 WSL

如果您想了解更多信息,可以阅读 关于 部分。

特性

  • 将文件列为主要为 ArchiveItem 数组
    • 使用 getFileItems() 方法:文件列表
    • 使用 getFileItem(string $path) 方法:与 path 属性对应的文件
    • 使用 getFirst() 方法:第一个文件
    • 使用 getLast() 方法:最后一个文件
    • 使用 find() 方法:找到与 path 属性匹配的第一个文件
    • 使用 filter() 方法:找到所有与 path 属性匹配的文件
  • 文件内容
    • 使用 getContents() 方法:文件内容作为字符串(对于图像很有用)
    • 使用 getText() 方法:文本文件的内容(二进制文件返回 null
  • 提取文件
    • 使用 extract() 方法:将文件提取到目录
    • 使用extractAll()方法:将所有文件提取到目录中
  • stat函数对应的存档状态[stat]
  • PDF元数据:getTitle()getAuthor()getSubject()getCreator()getCreationDate()getModDate()getPages()
  • 文件计数
  • 创建或编辑存档,仅支持.zip格式
    • 使用make()方法:创建或编辑存档
    • 使用addFiles()方法:将文件添加到存档
    • 使用addFromString()方法:将字符串添加到存档
    • 使用addDirectory()addDirectories()方法:将目录添加到存档
    • 使用save()方法:保存存档

安装

您可以通过composer安装此包

composer require kiwilan/php-archive

用法

读取和提取

支持存档文件(.zip.rar.tar.7zepubcbzcbrcb7cbttar.gz.pdf)。

$archive = Archive::read('path/to/archive.zip');

$files = $archive->getFileItems(); // ArchiveItem[]
$count = $archive->getCount(); // int of files count

$images = $archive->filter('jpeg'); // ArchiveItem[] with `jpeg` in their path
$metadataXml = $archive->find('metadata.xml'); // First ArchiveItem with `metadata.xml` in their path
$content = $archive->getContents($metadataXml); // `metadata.xml` file content

$paths = $archive->extract('/path/to/directory', [$metadataXml]); // string[] of extracted files paths
$paths = $archive->extractAll('/path/to/directory'); // string[] of extracted files paths

PDF文件与存档使用相同的API,但有一些不同。

$archive = Archive::read('path/to/file.pdf');

$pdf = $archive->getPdf(); // Metadata of PDF

$content = $archive->getContents($archive->getFirst()); // PDF page as image
$text = $archive->getText($archive->getFirst()); // PDF page as text

从字符串读取

您可以使用readFromString方法从字符串中读取存档。

$archive = Archive::readFromString($string);

此方法将尝试从字符串中检测存档的格式。如果您遇到错误,您可以使用带有第三个参数的readFromString方法来指定存档的格式。

$archive = Archive::readFromString($string, extension: 'zip');

受密码保护

您可以使用readreadFromString方法读取受密码保护的存档。

警告

仅适用于存档,不适用于PDF文件。

$archive = Archive::read('path/to/password-protected-archive.zip', 'password');

覆盖二进制路径

对于p7zip二进制文件,您可以使用overrideBinaryPath方法覆盖路径。

$archive = Archive::read($path)->overrideBinaryPath('/opt/homebrew/bin/7z');

状态

stat PHP函数:[https://php.ac.cn/manual/en/function.stat.php]

提供有关文件的信息

$archive = Archive::read('path/to/file.zip');
$stat = $archive->stat();

$stat->getPath(); // Path of file
$stat->getDeviceNumber(); // Device number
$stat->getInodeNumber(); // Inode number
$stat->getInodeProtectionMode(); // Inode protection mode
$stat->getNumberOfLinks(); // Number of links
$stat->getUserId(); // User ID
$stat->getGroupId(); // Group ID
$stat->getDeviceType(); // Device type
$stat->getSize(); // Size of file
$stat->getLastAccessAt(); // Last access time
$stat->getCreatedAt(); // Creation time
$stat->getModifiedAt(); // Last modification time
$stat->getBlockSize(); // Block size
$stat->getNumberOfBlocks(); // Number of blocks
$stat->getStatus(); // Status

创建

您可以使用Archive::make方法创建存档。

仅适用于.zip存档。

$archive = Archive::make('path/to/archive.zip');
$files = [
    'path/to/file/in/archive-file1.txt' => 'path/to/real-file1.txt',
    'path/to/file/in/archive-file2.txt' => 'path/to/real-file2.txt',
    'path/to/file/in/archive-file3.txt' => 'path/to/real-file3.txt',
];

foreach ($files as $pathInArchive => $pathToRealFile) {
    $archive->addFile($pathInArchive, $pathToRealFile);
}
$archive->addFromString('test.txt', 'Hello World!');
$archive->addDirectory('./directory', 'path/to/directory');
$archive->save();

编辑

您可以使用与Archive::make相同的方法编辑存档。

$archive = Archive::make('path/to/archive.zip');
$archive->addFromString('test.txt', 'Hello World!');
$archive->save();

测试

composer test

关于

此包受到StackOverflow上这篇优秀帖子[此帖子]的启发,该帖子介绍了PHP存档处理的最新技术。Gemorroj/Archive7z包也是一个很好的灵感来源,因为它是目前唯一一个使用p7zip二进制文件的包装器来处理.7z存档的包。但我希望如果可能的话,使用原生PHP解决方案来处理所有主要存档格式,并在原生解决方案不可用的情况下使用p7zip二进制文件。

PHP存档处理的最新技术

  • 使用ZipArchive处理.zip
  • 使用PharData处理.tar
  • 如果安装了rar扩展,使用RarArchive处理.rar
  • 无法使用原生PHP解决方案处理.7z

为什么不完全包装p7zip二进制文件?

此解决方案由Gemorroj/Archive7z使用,并且效果良好。但另一个问题是使用p7zip分支,这不是官方的p7zip二进制文件,并且可能在某些系统上难以安装。

PHP可以原生处理某些存档格式,但并非所有。因此,当可能时,我选择使用原生PHP解决方案,并在不可能时使用官方版本的p7zip二进制文件。

rar的情况

PHP默认没有安装rar PHP扩展,开发者需要手动安装。这个扩展没有活跃维护,用户可能会遇到一些编译问题。要在PHP 8.1或8.2上安装它,需要手动编译扩展,如果您想安装,可以阅读这个指南(对于PHP 8.2,您将收到一个警告消息,但这不是问题,扩展将正常工作)。

rar PHP扩展是一个问题,因为它与未来PHP版本的兼容性不确定。因此,如果rar PHP扩展没有安装,我选择使用p7zip二进制文件来处理rar存档。

关于7zip的情况

PHP不能原生处理.7z存档,因此我选择使用p7zip二进制文件。您需要在系统上安装它才能使用此软件包。如果您想安装,可以阅读这个指南

关于pdf的情况

PHP不能原生处理.pdf存档,因此我选择使用嵌入在此包中的smalot/pdfparser软件包。要提取页面为图像,您需要安装imagick扩展,如果您想安装,可以阅读这个指南

电子书和漫画

此包可以处理.epub.cbz.cbr.cb7.cbt存档,这取决于扩展,请查看要求部分。

更多

替代方案

文档

变更日志

请参阅CHANGELOG以获取有关最近更改的更多信息。

致谢

许可证

MIT许可证(MIT)。请参阅许可证文件以获取更多信息。