• 日常搜索
  • 百度一下
  • Google
  • 在线工具
  • 搜转载

如何在PHP中压缩和解压缩文件

通过 Internet 传输文件时压缩文件有很多优点。在大多数情况下,压缩格式的所有文件的总大小都会大幅下降。这意味着您将节省一些带宽,用户也将获得更快的下载速度。用户下载文件后,可以随时解压缩。简而言之,压缩可以让您和您的访问者更轻松地通过 Internet 提供文件。

可能会阻止您压缩文件或使过程非常烦人的一个因素是您可能手动执行此操作。幸运的是,php 附带了许多专门处理文件压缩和提取的扩展。您可以使用这些扩展中提供的功能在 PHP 中自动压缩文件。

本教程将教您如何在 PHP 中将文件压缩和解压缩(压缩和解压缩)到 zip 归档文件中。您还将学习如何删除或重命名存档中的文件,而无需先提取它们。

在 PHP 中压缩文件

PHPZipArchive类有很多属性和方法可以帮助您压缩和解压缩所有文件。

压缩单个文件

您可以一次将一个文件添加到您的 zip 存档中,也可以一次添加整个目录。无论哪种情况,第一步都是创建一个新ZipArchive实例,然后调用该open($filename, [$flags])方法。此方法将打开一个新的 zip 存档以进行读取、写入或其他修改。$flag可选参数有四个有效值,用于确定如何处理不同的情况。

  • ZipArchive::OVERWRITE— 如果指定存档中的内容已经存在,此标志将覆盖它。

  • ZipArchive::CREATE— 如果该标志尚不存在,则该标志将创建一个新存档。

  • ZipArchive::EXCL— 如果存档已存在,此标志将导致错误。

  • ZipArchive::CHECKCONS— 该标志将告诉 PHP 对存档执行额外的一致性检查,如果检查失败则给出错误。

您可以查看此方法的文档以了解在打开文件失败时返回的不同错误代码。如果 zip 文件打开或创建成功,该方法将返回true.

成功打开存档后,您可以使用该addFile($filename, $localname, $start, $length)方法将给定路径中的任何文件添加到存档中。该$filename参数是要添加到存档的文件的路径。该$localname参数用于为文件分配名称以将其存储在存档中。addFile()每次想要将新文件添加到存档时,您都可以调用。

将所有必要的文件添加到存档后,您只需调用该close()方法即可将其关闭并保存更改。

假设您有一个网站,允许用户下载不同字体的字体文件以及使用它们的许可信息。像这样的文件将是使用 PHP 自动归档的完美示例。以下代码向您展示了如何做到这一点。

<?php

$zip = new ZipArchive();
$zip->open('compressed/font_files.zip', ZipArchive::CREATE);
 
$zip->addFile('fonts/Monoton/Monoton-Regular.ttf', 'Monoton-Regular.ttf');
$zip->addFile('fonts/Monoton/OFL.txt', 'license.txt');
 
$zip->close();

?>

我们首先创建一个ZipArchive实例,然后使用该open()方法创建我们的存档。该addFile()方法将我们实际的.ttf字体文件和.txt许可证文件添加到存档中。

您应该注意原始文件位于fonts/Monoton目录中。但是,PHP 代码将其直接放在我们存档的根目录中。您可以更改目录结构以及存档中文件的名称。

压缩目录中的多个文件

一段时间后,将单个文件添加到您的存档中可能会很累。例如,您可能想要创建所有. 目录中的pdf或.png文件。在这种情况下,该addGlob($pattern, $flags, $options)方法将非常有用。此方法的唯一缺点是您无法控制存档中单个文件的位置。但是,您仍然可以使用该$options参数影响存档内的目录结构。选项以关联数组的形式传递。

  • add_path— 您分配的值add_path以存档中文件的本地路径为前缀。

  • remove_path—您分配的值用于从添加到存档的不同文件的路径中remove_path删除匹配的前缀。

  • remove_all_path—将值设置remove_all_path为true将删除文件路径中除文件名之外的所有内容。在这种情况下,文件将添加到存档的根目录。

重要的是要记住,路径的删除是在add_path.

以下代码片段将使addGlob()所有这些选项的使用更加清晰。

$zip = new ZipArchive();
$zip->open('compressed/user_archive.zip', ZipArchive::CREATE);
 
$options = array('add_path' => 'light_wallpapers/', 'remove_all_path' => TRUE);
$zip->addGlob('lights/*.jpg', 0, $options);

$options = array('add_path' => 'font_files/', 'remove_all_path' => TRUE);
$zip->addGlob('documents/*.ttf', 0, $options);

$options = array('add_path' => 'pdf_books/', 'remove_all_path' => TRUE);
$zip->addGlob('documents/*.pdf', 0, $options);

$options = array('add_path' => 'images/', 'remove_all_path' => TRUE);
$zip->addGlob('documents/*.{jpg, png}', GLOB_BRACE, $options);
 
$zip->close();

像往常一样,我们首先创建一个ZipArchive实例,然后使用该open()方法创建我们的存档。每次调用方法之前,我们还为数组中的add_path键指定不同的值 。这样,我们可以一次处理一组特定的文件,并相应地提供归档选项。$optionsaddGlob()

在第一种情况下,我们遍历lights目录中的所有.jpg文件,并将它们放置在归档文件的 light_wallpapers目录中。同样,我们遍历 文档目录中的所有.ttf文件,然后将它们放入存档中名为font_files的文件夹中。最后,我们一次遍历文档中的所有.jpg和.png文件,并将它们全部放在images目录中。

如您所见,$options参数中的值对于组织存档内的内容很有用。

从档案中提取内容

该类ZipArchive有一个方法被调用extractTo($destination, $entries)来提取档案的内容。您可以使用它来提取存档中的所有内容或仅提取一些特定文件。该$entries参数可用于指定要提取的单个文件名,也可以使用它来传递文件数组。

要记住的重要一点是,您需要在存档中指定文件的正确路径才能提取它。例如,我们在上一节中归档了一个名为AlegreyaSans-Light.ttf的字体文件。该文件存储在存档中名为font_files的目录中。这意味着您需要在$entries参数中指定的路径是font_files/AlegreyaSans-Light.ttf而不仅仅是AlegreyaSans-Light.ttf。

提取过程中会保留目录和文件结构,文件将被提取到各自的目录中。

<?php

$zip = new ZipArchive();
$zip->open('compressed/user_archive.zip', ZipArchive::CREATE);
$zip->extractTo('uncompressed/', 'font_files/AlegreyaSans-Light.ttf');
$zip->close();
 
?>

如果省略第二个参数,该方法将提取存档中的所有文件。

获得对档案的更多控制权

该类ZipArchive还具有许多其他方法和属性,可帮助您在提取其所有内容之前获取有关存档的更多信息。

count()您可以使用该方法计算存档中的文件数。另一种选择是使用该numFiles属性。它们可用于遍历存档中的所有文件并仅提取您需要的文件 - 或者您可以对它们执行其他操作,例如从存档中删除它们。

在以下示例中,我们将删除存档中包含单词Italic的所有文件。类似的代码可用于删除所有不包含特定单词的文件。您还可以遍历这些文件并将特定单词替换为其他单词。

<?php

$zip = new ZipArchive();
$zip->open('compressed/user_archive.zip', ZipArchive::CREATE);

$file_count = $zip->count();

for($i = 0; $i < $file_count; $i++) {
    $file_name = $zip->getNameIndex($i);

    if(stripos($file_name, 'Italic') !== false) {
        $zip->deleteName($file_name);
    }
}
 
$zip->close();

?>

在上面的代码中,我们deleteName()用于删除单个文件。但是,您也可以使用它来删除整个目录。

类似的功能renameName($oldname, $newname)可用于更改存档中任何文件的名称。$newname如果标题为的文件已存在,您将收到错误消息。

最后的想法

我们已经介绍了ZipArchive该类的许多非常有用的方法,它们将使 PHP 中文件的自动压缩和提取变得轻而易举。您现在应该能够根据自己的标准一次压缩单个文件或一组文件。同样,您应该能够从存档中提取任何特定文件而不会影响其他内容。


文章目录
  • 在 PHP 中压缩文件
    • 压缩单个文件
    • 压缩目录中的多个文件
  • 从档案中提取内容
  • 获得对档案的更多控制权
  • 最后的想法