当前位置: 首页 > 工具软件 > PclZip > 使用案例 >

PclZIP使用文档

赵高雅
2023-12-01

PclZIP使用文档

文档来源:https://viky-zhang.gitbooks.io/pclzip/top/downloads.html 

个人博客:http://www.phpnotes.top/2017/11/24/php/28/

1. 如何使用

1.1. PKZIP 压缩包的内部表示方式

每个 PKZIP 压缩包都由一个 PclZip 对象表示。 当使用 PclZip 对象创建一个 PclZip 压缩包时,需绑定压缩包的名字。 此时,PclZip 不会检查压缩包,也不可读,甚至压缩包还不存在。

require_once('pclzip.lib.php');

$archive = new PclZip("archive.zip");

此压缩包后续将由此 PclZip 对象进行操作控制。

想新建一个不存在的压缩包,应使用create()方法,并可传入一些参数,如文件或目录的列表。

1.2. 方法参数与运行参数

每个方法都有自己的参数,这些参数的使用可见每个方法的介绍页面。这些参数可能是必须也可能是可选的,例如:

require_once('pclzip.lib.php');

$archive = new PclZip('archive.zip');

$v_list = $archive->add('dev/file.txt', PCLZIP_OPT_REMOVE_PATH, 'dev');

上面,第 1 个参数dev/file.txt是必须参数,PCLZIP_OPT_REMOVE_PATH是可选参数。

有些方法只需一些可选参数:

$list = $archive->extract(

PCLZIP_OPT_PATH, "folder",

PCLZIP_OPT_REMOVE_PATH, "data",

PCLZIP_CB_PRE_EXTRACT, "callback_pre_extract",

PCLZIP_CB_POST_EXTRACT, "callback_post_extract"

);

上面参数表示:解压到目录folder,如压缩包内有路径是data则去掉此路径。

此外,每个文件在解压出来前都会自动调用一个回调函数callback_pre_extract(), 此回调函数可用于修改将解压到的路径或跳过不解压此文件。

每个文件在解压完毕后都会自动调用一个回调函数,可用于在解压下一个文件前做一些相关操作。

$list = $archive->extract(

PCLZIP_OPT_PATH, "folder",

PCLZIP_OPT_REMOVE_ALL_PATH

);

上面例子的作用是解压所有文件到folder目录,并且原来在压缩包内的所有文件的路径都将被去掉 (译注:即所有层次的文件都将被解压到folder根目录)。此示例中,可无需指明针对哪个文件的路径。

以上这些示例大致演示了如何使用参数。基于此方式使用参数,可提供更好的功能(代价是稍增加了复杂度)。 这样的参数设计,也简化了每个方法函数的设计。

更详细的参数使用方式,可见于参数选项页面。并且,每个方法的参数描述中都将由详细的说明。

1.3. 返回值

每个方法的返回值可能不一样,详细见每个方法的介绍页面。

但大部分方法都在出错时返回0(以及错误标记),在成功时返回一个描述每个文件的数组。、 此数组的每项包括有一个文件或目录的属性信息和最后操作该文件的状态。

下表列出了每个文件包含的信息:

  • filename:文件名。添加到压缩包时,此变量代表调用方法是的参数;解压出来时,代表解压后的文件名
  • stored_filename:压缩包内存储的文件名
  • size:文件的实际大小
  • compressed_size:压缩后的文件大小(不包含头部)
  • mtime:文件的最后修改日期和时间(UNIX 时间戳)
  • comment:此文件的注释文字
  • folder:true | false:表示文件或是目录
  • index:文件在压缩包内的索引(当已设置时)
  • content:文件解压后的内容。此变量仅当已设置PCLZIP_OPT_EXTRACT_IN_STRING参数时才存在
  • status:操作的结果状态(根据每个操作而不同)
    • ok:成功 OK!
    • filtered:此文件/目录已被用户设置不解压处理
    • already_a_directory:此文件没有解压,因为一个同名的目录已存在
    • newer_exist:此文件没有解压,因为已有同名文件存在,且该文件已被写保护
    • write_protected:此文件没有解压,因为已有同名解压出来了(the file was not extracted because a more recent file exists.)
    • path_creation_fail:此文件没有解压,因为文件目录没有创建成功
    • write_error:此文件没有解压,因为出现写错误
    • read_error:此文件没有解压,因为出现读错误
    • invalid_header:此文件没有解压,因为头信息不正确
    • skipped:此文件没有解压或添加到压缩包,因为用户已在回调函数中跳过此文件
    • filename_too_long:文件名太长而没有被添加到压缩包中(最大 255 字符)(3开始引入)

1. 可选参数(普通参数)

  • PCLZIP_OPT_PATH
  • PCLZIP_OPT_ADD_PATH
  • PCLZIP_OPT_REMOVE_PATH
  • PCLZIP_OPT_REMOVE_ALL_PATH
  • PCLZIP_OPT_SET_CHMOD
  • PCLZIP_OPT_BY_NAME
  • PCLZIP_OPT_BY_EREG
  • PCLZIP_OPT_BY_PREG
  • PCLZIP_OPT_BY_INDEX
  • PCLZIP_OPT_EXTRACT_AS_STRING
  • PCLZIP_OPT_EXTRACT_IN_OUTPUT
  • PCLZIP_OPT_NO_COMPRESSION
  • PCLZIP_OPT_COMMENT
  • PCLZIP_OPT_ADD_COMMENT
  • PCLZIP_OPT_PREPEND_COMMENT
  • PCLZIP_OPT_REPLACE_NEWER
  • PCLZIP_OPT_EXTRACT_DIR_RESTRICTION
  • PCLZIP_OPT_STOP_ON_ERROR
  • PCLZIP_OPT_TEMP_FILE_ON
  • PCLZIP_OPT_TEMP_FILE_THRESHOLD
  • PCLZIP_OPT_TEMP_FILE_OFF

参数有 2 大类:

  • 普通变量:传递操作信息到方法
  • 回调函数:供用户在 PclZip 处理过程中进行一些操作

回调函数可能有些难理解,不过可提供对压缩包更好的操作方式。

这些可选参数是一些常量,实质是一些静态整数。 参数对应的参数值,可以是单个值,也可以是一个列表。 有时某些参数无需设置值,因为参数名本身已包含了必须信息。

下面将列举所有的可选参数:

1.1. PCLZIP_OPT_PATH

此参数指明压缩包的内容将被解压到的目录。

参数值:一个字符串。

$list = $archive->extract(PCLZIP_OPT_PATH, "extract/folder/");

此参数可用于以下方法:

  • extract()
  • extractByIndex()

1.2. PCLZIP_OPT_ADD_PATH

此参数用于在解压或压缩时为文件添加路径。如,压缩时可将file.txt文件以backup/file.txt路径 放到压缩包中;解压时可将data/file.txt解压到folder/data/file.txt (译注:folder没有出现在下面例子中)。

$list = $archive->create(    "file.txt,image.gif",    PCLZIP_OPT_ADD_PATH, "backup");

此参数可用于以下方法:

  • create()
  • add()
  • extract()

1.3. PCLZIP_OPT_REMOVE_PATH

此参数用于在解压或压缩时去掉一些前缀路径。 如,压缩时可将/usr/local/user/test/file.txt压缩为test/file.txt; 解压时将压缩包内的folder/data/file.txt解压为data/file.txt。

参数值:一个字符串。

$list = $archive->add(    "/usr/local/user/test/file.txt",    PCLZIP_OPT_REMOVE_PATH, "/usr/local/user");

此参数可用于以下方法:

  • create()
  • add()
  • extract()
  • extractByIndex()

注意:在同一方法调用中,若已指定PCLZIP_OPT_REMOVE_ALL_PATH参数,则本参数将自动被忽略。

1.4. PCLZIP_OPT_REMOVE_ALL_PATH

此参数用于在解压或压缩时,去掉文件的所有路径(译注:即所有文件都放在根目录下,没有任何子目录)。

使用此参数时无需指定任何路径,有时简单理解为PCLZIP_OPT_REMOVE_PATH参数的批量操作。 但此参数使用时需注意,应保证不同子目录中不存在同名的文件。

本参数没有参数值。

$list = $archive->create(    "data/file.txt images/image.gif",    PCLZIP_OPT_REMOVE_ALL_PATH);// 上面会从 'data/file.txt' 中去掉 'data/'// 并从 'images/image.gif' 中去掉 'images/'

此参数可用于以下方法:

  • create()
  • add()
  • extract()
  • extractByIndex()

1.5. PCLZIP_OPT_SET_CHMOD

此参数用于在解压后对文件的权限进行修改。

在类 *NIIX 系统中,文件管理系统和文件拥有者一般不允许对系统的所有文件进行访问。 特别的,启动 PHP 进程的用户会对解压出来的文件进行保护,一般不允许其他用户对 其进行访问。

本参数会尝试对解压出来的文件的权限进行修改,如允许写访问,但不修改文件的拥有者。

参数值:一个八进制值(如 0777)

$list = $archive->extract(PCLZIP_OPT_SET_CHMOD, 0777);

此参数可用于以下方法:

  • extract()
  • extractByIndex()

1.6. PCLZIP_OPT_BY_NAME

此参数用于只解压出某些文件/目录。

(译注:下面例子假设test.zip压缩包中至少有这两个文件)

$archive = new PclZip('test.zip');$rule_list[0] = 'data/file1.txt';$rule_list[1] = 'data/file2.txt';$list = $archive->extract(PCLZIP_OPT_BY_NAME, $rule_list);if ($list == 0) {    echo "ERROR : " . $archive->errorInfo(true);}

参数值,允许两种情况:

  • 一个数组
  • 一个字符串,字符串内文件列表用英文逗号隔开

$archive = new PclZip('test.zip');$list = $archive->extract(PCLZIP_OPT_BY_NAME, "data/file1.txt,data/file2.txt");if ($list == 0) {    echo "ERROR : " . $archive->errorInfo(true);}

1.7. PCLZIP_OPT_BY_EREG

此参数用于以正则表达式的方式过滤将被解压的文件/目录。

此参数基于 PHP 自带的 ereg() 函数。 (译注:ereg 在 PHP7 中将不能用)

$archive = new PclZip('test.zip');$list = $archive->extract(PCLZIP_OPT_BY_EREG, "txt$");if ($list == 0) {  echo "ERROR : " . $archive->errorInfo(true);}

1.8. PCLZIP_OPT_BY_PREG

此参数用于以正则表达式的方式过滤将被解压的文件/目录。

此参数基于 PHP 自带的 preg_match() 函数。 (译注:建议使用本参数,而非PCLZIP_OPT_BY_EREG)

$archive = new PclZip('test.zip');$list = $archive->extract(PCLZIP_OPT_BY_PREG, "txt$");if ($list == 0) {  echo "ERROR : " . $archive->errorInfo(true);}

1.9. PCLZIP_OPT_BY_INDEX

此参数允许以指定压缩包内的文件索引方式来解压文件/目录。

$archive = new PclZip('test.zip');$list = $archive->extract(PCLZIP_OPT_BY_INDEX, ['0-4', '2-7', '10-33']);if ($list == 0) {  echo "ERROR : " . $archive->errorInfo(true);}

1.10. PCLZIP_OPT_EXTRACT_AS_STRING

此参数用于将压缩包内的文件内容直接解压到 PHP 字符串中,而非文件中,不依赖文件系统。

此参数的用途,如:

  • 显示一个 readme 文件
  • 直接将压缩包内文件的内容直接显示在标准输出中(见参数PCLZIP_OPT_EXTRACT_IN_OUTPUT)

若想将压缩包内的所有文件都解压到 PHP 字符串中,将消耗较大的内存,请防止内存使用超过 PHP 配置的限制。

$archive = new PclZip('test.zip');$list = $archive->extract(    PCLZIP_OPT_BY_NAME, "data/readme.txt",    PCLZIP_OPT_EXTRACT_AS_STRING);if ($list == 0) {  echo "ERROR : " . $archive->errorInfo(true);  exit;}echo $list[0]['content'];

1.11. PCLZIP_OPT_EXTRACT_IN_OUTPUT

此参数用于直接将压缩包内文件的内容直接显示在标准输出中(类似echo的功能)。

$archive = new PclZip('test.zip');$list = $archive->extract(    PCLZIP_OPT_BY_NAME, "data/readme.txt",    PCLZIP_OPT_EXTRACT_IN_OUTPUT);if ($list == 0) {  echo "ERROR : " . $archive->errorInfo(true);}

1.12. PCLZIP_OPT_NO_COMPRESSION

此参数用于添加不压缩的文件到压缩包。

$archive = new PclZip('test.zip');$list = $archive->add("data/file.txt", PCLZIP_OPT_NO_COMPRESSION);if ($list == 0) {  echo "ERROR : " . $archive->errorInfo(true);}

1.13. PCLZIP_OPT_COMMENT

此参数用于为压缩包内的文件设置一个注释字符串,若已有注释,将替换原有注释。

$archive = new PclZip('test.zip');$list = $archive->create(    "data",     PCLZIP_OPT_COMMENT, "Add a comment");if ($list == 0) {  echo "ERROR : " . $archive->errorInfo(true);}

1.14. PCLZIP_OPT_ADD_COMMENT

此参数用于为压缩包内的文件添加注释字符串,若已有注释,则追加到已有注释后面。

$archive = new PclZip('test.zip');$list = $archive->add(    "data",     PCLZIP_OPT_ADD_COMMENT, "Add a comment after the existing one");if ($list == 0) {  echo "ERROR : " . $archive->errorInfo(true);}

1.15. PCLZIP_OPT_PREPEND_COMMENT

此参数用于为压缩包内的文件添加注释字符串,若已有注释,则添加到已有注释之前。

$archive = new PclZip('test.zip');$list = $archive->add(    "data",     PCLZIP_OPT_PREPEND_COMMENT, "Add a comment before the existing one");if ($list == 0) {  echo "ERROR : " . $archive->errorInfo(true);}

1.16. PCLZIP_OPT_REPLACE_NEWER

默认情况下,PclZip 解压文件时,若文件系统中已存在文件,有两种情况:

  • 文件系统中的文件时间比压缩包内的文件时间旧,则解压时替换已有文件
  • 文件系统中的文件时间比压缩包内的文件时间新,则解压时不替换已有文件

本参数用于替换所有已有文件,不管时间新旧。

这对于还原一个备份时比较有用。

$archive = new PclZip('test.zip');$list = $archive->extract(    PCLZIP_OPT_BY_NAME, "data/readme.txt",    PCLZIP_OPT_REPLACE_NEWER);if ($list == 0) {    echo "ERROR : " . $archive->errorInfo(true);}

1.17. PCLZIP_OPT_EXTRACT_DIR_RESTRICTION

PclZip 允许解压文件到系统的任意位置,但有人想通过解压到某些位置来覆盖系统文件(如密码文件)或其他文件, 这不安全。

此参数可用于只允许解压到指定目录,而不能解压到其他目录。

此参数可方便的以少量代码减少一些简单的错误。

注意:若要更安全的目录限制,请使用 PHP 的配置选项。

下面例子将不允许任何解压到非/var/www/data目录中。

$archive = new PclZip('test.zip');$list = $archive->extract(PCLZIP_OPT_EXTRACT_DIR_RESTRICTION, "/var/www/data");if ($list == 0) {    echo "ERROR : " . $archive->errorInfo(true);}

1.18. PCLZIP_OPT_STOP_ON_ERROR

默认情况下,解压时,若遇到某些文件不能成功解压,PclZip 并不会自动停止后面文件的解压。 全部解压完毕后,将返回一个解压后的文件列表状态结果(可见于extract()页面)。 列表中的每个值都包含每个文件/目录的解压状态。

本参数用于在解压遇到 1 个文件解压失败时就立即停止后续文件的解压。 这可方便你在解压刚出错后进行一些已解压文件的清理或其他操作。

$archive = new PclZip('test.zip');$list = $archive->extract(    PCLZIP_OPT_ADD_PATH, "extract_folder/",    PCLZIP_OPT_STOP_ON_ERROR);if ($list == 0) {  if ($archive->errorCode() == PCLZIP_ERR_ALREADY_A_DIRECTORY) {    echo "ERROR : File tries to replace a folder !";  }}

1.19. PCLZIP_OPT_TEMP_FILE_ON

1.20. PCLZIP_OPT_TEMP_FILE_OFF

1.21. PCLZIP_OPT_TEMP_FILE_THRESHOLD

PclZip 从 v2.7 开始支持压缩或解压时使用临时文件,以更好支持大文件。

大部分情况下,PclZip 都在内存中进行操作,如读取所有文件、压缩文件、写文件到压缩包中。 使用临时文件时,PclZip 在压缩文件时将每次只读取大文件的其中一小块(2048 字节), 并直接将已压缩的小块先写入到临时文件中。当临时文件已写入到压缩包中,则删除该临时文件。

在 v2.8 中,解压时也支持类似的临时文件机制。

当压缩或解压大文件时,PclZip 很快会超过 PHP 配置中设置的内存限制(php.ini文件中的memory_limit选项) 而导致操作失败。通过使用临时文件,对大文件操作时将提高操作成功率。 但是,相对于在内存中操作,使用临时文件会降低性能。

从 v2.7 开始,PclZip 能自动检测文件的大小,并根据memory_limit的选择值,判断是否该采用临时文件方案。 有下面几个参数可配置:

  • PCLZIP_OPT_ADD_TEMP_FILE_ON

全部使用临时文件

  • PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD

超出本参数阈值大小的文件将使用临时文件,否则使用内存

  • PCLZIP_OPT_ADD_TEMP_FILE_OFF

全部使用内存,全部不使用临时文件

PCLZIP_OPT_TEMP_FILE_ON的示例:

include_once('pclzip.lib.php'); $archive = new PclZip('archive.zip');$v_list = $archive->create(    'data/image-1.jpg,data/image-2.jpg',    PCLZIP_OPT_REMOVE_PATH, 'data',    PCLZIP_OPT_ADD_TEMP_FILE_ON);if ($v_list == 0) {    die("Error : " . $archive->errorInfo(true));}

PCLZIP_OPT_TEMP_FILE_THRESHOLD的示例:

include_once('pclzip.lib.php'); $archive = new PclZip('archive.zip');$v_list = $archive->create(    'data/image-1.jpg,data/image-2.jpg',    PCLZIP_OPT_REMOVE_PATH, 'data',    PCLZIP_OPT_TEMP_FILE_THRESHOLD, 10);if ($v_list == 0) {    die("Error : " . $archive->errorInfo(true));}

PCLZIP_OPT_TEMP_FILE_OFF的示例:

include_once('pclzip.lib.php');ini_set('memory_limit', '180M');$archive = new PclZip('archive.zip');$v_list = $archive->create(    'data/image-1.jpg,data/image-2.jpg',    PCLZIP_OPT_REMOVE_PATH, 'data',    PCLZIP_OPT_TEMP_FILE_OFF);if ($v_list == 0) {    die("Error : " . $archive->errorInfo(true));}

此参数可用于以下方法:

  • create()
  • add()
  • extract()
  • extractByIndex()

注意:本参数将取代下面这些参数(若存在)

  • PCLZIP_OPT_ADD_TEMP_FILE_ON
  • PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD
  • PCLZIP_OPT_ADD_TEMP_FILE_OFF

2. 可选参数(回调函数)

回调函数(Call-back)可作为一种特殊参数,因为其中是一个函数名。 回调函数应严格遵守一些约定,并有不同的分类。 回调函数中可以做任何事,但都应接收约定的参数,并返回约定的值。 回调函数中不应进行一些特殊的操作,如在处理过程中把压缩包删除了,这是不合理的。

2.1. PCLZIP_CB_PRE_EXTRACT(解压前的回调)

本参数用于在解压压缩包内的每个文件前执行一些操作,包括:

  • 修改解压后的文件路径或文件名
  • 跳过某些文件(即不解压压缩包内某些文件)

此回调函数是在以下参数发生作用后执行的:

  • PCLZIP_OPT_PATH
  • PCLZIP_OPT_ADD_PATH
  • PCLZIP_OPT_REMOVE_PATH
  • PCLZIP_OPT_REMOVE_ALL_PATH

但会在相关检查之前执行(如文件不存在、目录不存在)。

本回调函数作为一个参数值放到 PclZip 的方法中,并应遵循下面约定:

function myCallBack($p_event, &$p_header){    // ... 你的逻辑代码 ...    return $result;}

当 PclZip 方法调起回调函数时,会给回调函数传入两个变量:

  • $p_event:回调参数的标识符(在这里就是PCLZIP_CB_PRE_EXTRACT),多个回调函数使用同一个函数时会比较有用。
  • $p_header:将被解压的文件的信息,是一个数组,里面包含几个信息字段。其中常用的是:
    • 压缩包内的文件名
    • 想解压到的文件位置

更详细的$p_header结构见返回值页面。

本回调函数中$p_header中可以被修改的字段:

  • filename字段,即想解压到的文件位置。
  • 其他字段,均只读,不能修改

本回调函数的返回值应是以下值之一:

  • 0:表示跳过,不解压当前文件
  • 1:表示解压将继续,只是可能会按照本回调函数中修改的文件名进行解压
  • 2:表示跳过,不解压当前文件,也不再解压后续的文件
  • 其他值:为未来备用(译注:n 年过去了貌似这个未来还没到)

function myPreExtractCallBack($p_event, &$p_header){    $info = pathinfo($p_header['filename']);    // ----- 跳过 gif 格式文件    if ($info['extension'] == 'gif') {      return 0;    }    // ----- 所有 jpg 文件都解压到 images 目录    else if ($info['extension'] == 'jpg') {      $p_header['filename'] = 'images/' . $info['basename'];      return 1;    }    // ----- 其他所有文件都直接正常解压    else {      return 1;    }} $list = $archive->extract(    PCLZIP_OPT_PATH, 'folder',    PCLZIP_CB_PRE_EXTRACT, 'myPreExtractCallBack');

上述例子中,实现了以下功能:

  • 跳过 gif 格式文件
  • 所有 jpg 文件都解压到 images 目录
  • 其他所有文件都直接正常解压

2.2. PCLZIP_CB_POST_EXTRACT(解压后的回调)

本参数用于在解压压缩包内的每个文件后执行一些操作, 本参数不会对解压过程本身进行修改,但作用包括:

  • 重命名已解压的文件/目录
  • 删除已解压的文件/目录

本回调函数作为一个参数值放到 PclZip 的方法中,并应遵循下面约定:

function myCallBack($p_event, &$p_header){    // ... 你的逻辑代码 ...    return $result;}

当 PclZip 方法调起回调函数时,会给回调函数传入两个变量:

  • $p_event:回调参数的标识符(在这里就是PCLZIP_CB_POST_EXTRACT),多个回调函数使用同一个函数时会比较有用。
  • $p_header:将被解压的文件的信息,是一个数组,里面包含几个信息字段。其中常用的是:
    • 解压后的文件名
    • 解压操作的执行状态

更详细的$p_header结构见返回值页面。

本回调函数中$p_header中的字段都不应被修改,因为所有字段都已包含了足够的信息。

本回调函数的返回值应是以下值之一:

  • 1:表示后续文件的解压将继续
  • 2:表示不再解压后续的文件
  • 其他值:为未来备用

function myPreExtractCallBack($p_event, &$p_header) { ... } function myPostExtractCallBack($p_event, &$p_header){    // ----- 判断是否已成功解压    if ($p_header['status'] == 'ok') {      // ----- 读取已解压文件内容到标准输入中      readfile($p_header['filename']);      // ----- 删除文件      unlink($p_header['filename'])    }} $list = $archive->extract(    PCLZIP_OPT_PATH, 'temp',    PCLZIP_CB_PRE_EXTRACT, 'myPreExtractCallBack',    PCLZIP_CB_POST_EXTRACT, 'myPostExtractCallBack');

上述例子中,实现了以下功能:

  • 将所有解压成功的文件内容输出到标准输出中
  • 并在解压后删除已解压的文件

注意:从 v2.1 开始,若想实现上述例子的功能,建议使用PCLZIP_OPT_EXTRACT_IN_OUTPUT参数, 而非本回调函数,因为那样就不会在文件系统中产生临时文件。

2.3. PCLZIP_CB_PRE_ADD(添加到压缩包前的回调)

本参数用于在添加文件到压缩包前执行一些操作,包括:

  • 修改被压缩文件在压缩包中的文件名或路径
  • 跳过,不添加某些文件到压缩包

此回调函数是在以下参数发生作用后执行的:

  • PCLZIP_OPT_PATH
  • PCLZIP_OPT_ADD_PATH
  • PCLZIP_OPT_REMOVE_PATH
  • PCLZIP_OPT_REMOVE_ALL_PATH

但会在检查文件名长度之前执行。

本回调函数作为一个参数值放到 PclZip 的方法中,并应遵循下面约定:

function myCallBack($p_event, &$p_header){    // ... 你的逻辑代码 ...    return $result;}

当 PclZip 方法调起回调函数时,会给回调函数传入两个变量:

  • $p_event:回调参数的标识符(在这里就是PCLZIP_CB_PRE_ADD),多个回调函数使用同一个函数时会比较有用。
  • $p_header:将被添加到压缩包的文件信息,是一个数组,里面包含几个信息字段。其中常用的是:
    • 文件压缩前的名字和路径
    • 文件在压缩包中的名字和路径

更详细的$p_header结构见返回值页面。

本回调函数中$p_header中可以被修改的字段:

  • filename字段,即文件在压缩包中的文件位置。
  • 其他字段,均只读,不能修改

本回调函数的返回值应是以下值之一:

  • 0:表示跳过,不添加当前文件当压缩包中,但会继续后续其他文件的添加
  • 1:表示压缩将继续,只是可能会按照本回调函数中修改的文件名进行压缩
  • 其他值:为未来备用

function myPreAddCallBack($p_event, &$p_header){    $info = pathinfo($p_header['stored_filename']);    // ----- bak 格式的文件跳过,不添加到压缩包    if ($info['extension'] == 'bak') {      return 0;    }    // ----- jpg 文件添加到压缩包时,放在压缩包内的 images 目录中    else if ($info['extension'] == 'jpg') {      $p_header['stored_filename'] = 'images/'.$info['basename'];      return 1;    }    // ----- 其他所有文件都按正常方式添加到压缩包中    else {      return 1;    }} $list = $archive->add(PCLZIP_CB_PRE_ADD, 'myPreAddCallBack');

上述例子中,实现了以下功能:

  • bak 格式的文件跳过,不添加到压缩包
  • jpg 文件添加到压缩包时,放在压缩包内的 images 目录中
  • 其他所有文件都按正常方式添加到压缩包中

2.4. PCLZIP_CB_POST_ADD(添加到压缩包后的回调)

本参数用于在添加文件到压缩包后执行一些操作,虽然不可修改已添加到压缩包内的文件,但可以:

  • 删除或修改文件系统中已添加到压缩包中的文件

本回调函数作为一个参数值放到 PclZip 的方法中,并应遵循下面约定:

function myCallBack($p_event, &$p_header){    // ... 你的逻辑代码 ...    return $result;}

当 PclZip 方法调起回调函数时,会给回调函数传入两个变量:

  • $p_event:回调参数的标识符(在这里就是PCLZIP_CB_POST_ADD),多个回调函数使用同一个函数时会比较有用。
  • $p_header:将已添加到压缩包的文件信息,是一个数组,里面包含几个信息字段。其中常用的是:
    • 文件在压缩包中的名字和路径

更详细的$p_header结构见返回值页面。

本回调函数中$p_header中的字段都不应被修改,因为所有字段都已包含了足够的信息。

本回调函数的返回值应是以下值之一:

  • 1:必须返回 1(译注:暂无解释)
  • 其他值:为未来备用

function myPostAddCallBack($p_event, &$p_header){    // ----- 判断添加到压缩包是否成功    if ($p_header['status'] == 'ok') {      // ----- 将文件系统中的文件移动到文件系统的 trash 目录      rename($p_header['filename'], 'trash/'.$p_header['filename'])    }} $list = $archive->extract(PCLZIP_CB_POST_ADD, 'myPostAddCallBack');

上述例子中,实现了以下功能:

  • 在添加到压缩包成功后,将文件系统中的文件移动到文件系统的 trash 目录

 

1. 错误处理

英文原文:http://www.phpconcept.net/pclzip/user-guide/20

从 v1.3 开始,PclZip 开始增加错误处理功能。 在此之前,只能通过外部的库来处理错误。 增加错误处理功能的主要原因是为了 1 个 PHP 文件就能使用 PclZip。 当然,你依然可以使用外部的库来处理错误,详见自定义 PclZip页面。

当一个方法的返回值是一个错误编号(大部分情况是 0)时, 可通过下面方法获取错误的相关信息:

  • errorName():返回错误的名称
  • errorCode():返回错误编号
  • errorInfo():返回错误的描述信息

后面是一些错误处理的示例。

1.1. 获取错误编号

$list = $archive->extract(PCLZIP_OPT_PATH, "extract/folder/");

if ($list == 0) {

die("Unrecoverable error, code " . $archive->errorCode());

}

 

// 输出:Unrecoverable error, code -6

1.2. 获取错误的名称

$list = $archive->extract(PCLZIP_OPT_PATH, "extract/folder/");

if ($list == 0) {

die("Unrecoverable error '" . $archive->errorName() . "'");

}

 

// 输出:Unrecoverable error 'PCLZIP_ERR_BAD_FORMAT'

1.3. 同时获取错误的名称和编号

$list = $archive->extract(PCLZIP_OPT_PATH, "extract/folder/");

if ($list == 0) {

die("Unrecoverable error '" . $archive->errorName(true) . "'");

}

 

// 输出:Unrecoverable error 'PCLZIP_ERR_BAD_FORMAT(-10)'

1.4. 获取错误的描述信息

$list = $archive->extract(PCLZIP_OPT_PATH, "extract/folder/");

if ($list == 0) {

die("Error : '" . $archive->errorInfo() . "'");

}

 

// 输出:Error : 'Invalid archive structure [code -10]'

1.5. 获取错误的全部信息

$list = $archive->extract(PCLZIP_OPT_PATH, "extract/folder/");

if ($list == 0) {

die("Error  : '" . $archive->errorInfo(true) . "'");

}

 

// 输出:Error : 'PCLZIP_ERR_BAD_FORMAT(-10) : Invalid archive structure'

1. 自定义 PclZip

PclZip 可通过配置一些静态常量来进行定制化。 但不建议你修改这些参数,除非你确实需要并且知道你很清楚你所做的是什么。 而且,当 PclZip 升级时,你还需重新配置这些参数。

下面将列举这些参数:

  • PCLZIP_READ_BLOCK_SIZE
  • PCLZIP_TEMPORARY_DIR
  • PCLZIP_SEPARATOR
  • PCLZIP_TEMPORARY_FILE_RATIO
  • PCLZIP_ERROR_EXTERNAL

1.1. PCLZIP_READ_BLOCK_SIZE

此值表示读取或写入一个文件时的分块大小。 你可根据你的操作系统的环境来修改本参数。

默认值:2048(译注:估计单位是字节)

1.2. PCLZIP_TEMPORARY_DIR

PclZip 在解压或压缩过程中可能会用到临时文件。 这些文件由 PclZip 来生成或删除。 默认的,临时文件的目录就是当前工作目录。这可能会引发一些问题,如当前目录是只读的。

本参数用于指定一个固定的临时文件目录。此目录必须是可读写的,并且必须已存在,PclZip 不会自动新建此目录。 建议使用绝对路径来定义此目录,并避免使用基于 Web 根目录的相对路径等。

此参数值最后必须以/结尾。

示例:

define('PCLZIP_TEMPORARY_DIR', '/usr/www/temp/');

include_once('pclzip.lib.php');

1.3. PCLZIP_SEPARATOR

在 v1.x 中,文件的分隔符是一个空格(这是一个不好的选择,特别是在 Windows 的路径中), 更好的选择是使用英文逗号,。 此常量用于设置该使用什么分隔符。

需注意的是:你修改此参数后,你原来的代码可能需要修改(若已使用了空格作为分隔符的话)。

若想修改为英文分号,示例:

define('PCLZIP_SEPARATOR', ';');

include_once('pclzip.lib.php');

1.4. PCLZIP_TEMPORARY_FILE_RATIO

PclZip 压缩或解译文件时可能会自动检测文件大小,并依据一定的阈值来决定是否使用临时文件。

本参数是一个比例值,阈值 = PHP内存大小限制(memory_limit)* 本阈值。

默认值:0.47。

推荐的值:< 0.5。

1.5. PCLZIP_ERROR_EXTERNAL

一个在新版 PclZip 已废弃的参数。

原本作用是:启用外部的错误处理库。

1. 错误定位

英文原文:http://www.phpconcept.net/pclzip/user-guide/24

原文是法文(PclZip 作者未翻译成英文):http://www.phpconcept.net/pclzip/user-guide/24

PclZip 有两个并存版本:

  • 正式版本
  • 错误跟踪版本

错误跟踪版本允许你捕获各种异常错误,如:

  • 文件权限
  • 系统错误
  • 系统其它限制等

示例:

require_once('pcltrace.lib.php');require_once('pclzip-trace.lib.php'); PclTraceOn(2); $zip = new PclZip('test.zip');$list = $zip->create("readme.txt");if ($list == 0) {    PclTraceDisplay();    die("Error : " . $zip->errorInfo(true));} PclTraceDisplay();

有三个方法来设置此功能:

  • PclTraceOn()
  • PclTraceOff()
  • PclTraceDisplay()

1.1. PclTraceOn()

1.1.1. 概述

此方法用于启用 trace 跟踪信息。 有不同级别可选。

1.1.2. 用法

PclTraceOn($level, $mode, $filename)

1.1.3. 参数

  • $level:错误跟踪的级别,范围:1 至 5 级,默认是 1。
  • $mode:错误跟踪的类型:
    • normal:错误跟踪信息会自动输出到 HTML 中(通常是浏览器)
    • memory:错误跟踪信息只能通过PclTraceDisplay()函数来获取
    • log:错误跟踪信息输出到日志文件中(现不可用)
  • $filename:日志文件的位置(现不可用)

1.1.4. 返回值

1.2. PclTraceOff()

1.2.1. 概述

此方法用于关闭错误跟踪信息。

1.2.2. 用法

PclTraceOff()

1.2.3. 参数

1.2.4. 返回值

1.3. PclTraceDisplay()

1.3.1. 概述

此方法用于显示错误跟踪信息。

1.3.2. 用法

PclTraceDisplay()

1.3.3. 参数

1.3.4. 返回值

1. zip 压缩格式

英文原文:http://www.phpconcept.net/pclzip/user-guide/25

PclZip 支持的压缩格式是 PKZIP,PKZIP 格式的详细信息见:http://www.phpconcept.net/pclzip/pkzip.txt。

译注:

  • PKZIP 是一个支持 zip 压缩格式的软件
  • 估计 PclZip 作者想表达的就是通用的 zip 格式而已,而非 PKZIP 特有的格式。
  • 实际使用起来,PclZip 与 PKZIP 并无关系
  • 上面的 PKZIP 链接已失效(404)

下面是 zip 压缩包格式的概述:

  1. 压缩包内的每个文件/目录,都有一个头信息,里面存储了文件的文件名、文件大小等信息。 数据压缩采用的是 GZIP 算法,详见:http://www.phpconcept.net/pclzip/rfc1952-gzip.txt。

译注:原文的 GZIP 链接已失效(404)

  1. 在压缩包的最后位置专门存储压缩包内每个文件的属性信息和整个压缩包的属性信息。 这样的好处是:无需解释整个压缩包就可快速获得压缩包的概要信息。
  2. PKZIP 格式定义了很多强大的属性,但 PclZip 至今仍不支持。 此外,PclZip 不支持由多个磁盘压缩组成的 zip 包。

译注:

  • 估计 PKZIP 中很多属性不是 zip 规范的。
  • 不太理解PclZip 不支持由多个磁盘压缩组成的 zip 包 的意思,不过一般也不会碰到此问题。

1. 方法列表

英文原文:http://www.phpconcept.net/pclzip/user-guide/21

  • PclZip::PclZip() : 构造函数
  • PclZip::create() : 创建 PKZIP 压缩包,并向其添加文件和目录
  • PclZip::listContent() : 列出压缩包中的内容
  • PclZip::extract() : 提取压缩包中的所有或部分内容
  • PclZip::properties() : 获取压缩包的属性信息
  • PclZip::add() : 向压缩包中添加文件或目录
  • PclZip::delete() : 删除压缩包中的内容
  • PclZip::merge() : 将一个压缩包的所有内容添加到另一个压缩包
  • PclZip::duplicate() : 复制压缩包

1. 方法:PclZip::PclZip

英文原文:http://www.phpconcept.net/pclzip/user-guide/52

1.1. 概述

本方法是 PclZip 对象的构造函数。

1.2. 用法

PclZip($zip_filename)

1.3. 参数

  • $zip_filename:PKZIP 压缩包的文件名

1.4. 描述

本方法创建一个表示 PKZIP 的 PclZip 对象,只需一个文件名参数,并执行一些检查,没有其他操作。

本构造函数会检查 PHP 的zlib扩展是否可用。若不可用,将终止执行,并产生错误信息。

1.5. 示例

require_once('pclzip.lib.php'); $archive = new PclZip('archive.zip');if ($archive->create('file.txt data/text.txt folder/') == 0) {    die('Error : ' . $archive->errorInfo(true));}

1. 方法:PclZip::create

英文原文:http://www.phpconcept.net/pclzip/user-guide/53

1.1. 概述

本方法用于根据输入的文件创建一个 PKZIP 压缩包文件。

1.2. 用法

PclZip::create($filelist, [可选参数])

1.3. 参数

  • $filelist:文件列表,可以是以下内容
    • 一个数组,每个数组项是一个文件或目录名
    • 一个字符串:一个文件或目录名
    • 一个字符串:一堆文件或目录名,并以英文逗号,分隔
  • 支持的可选参数
    • PCLZIP_OPT_REMOVE_PATH
    • PCLZIP_OPT_REMOVE_ALL_PATH
    • PCLZIP_OPT_ADD_PATH
    • PCLZIP_CB_PRE_ADD
    • PCLZIP_CB_POST_ADD
    • PCLZIP_OPT_NO_COMPRESSION
    • PCLZIP_OPT_COMMENT
    • PCLZIP_OPT_TEMP_FILE_THRESHOLD
    • PCLZIP_OPT_TEMP_FILE_ON
    • PCLZIP_OPT_TEMP_FILE_OFF

更多见可选参数页面。

1.4. 返回值

可能的返回值:

  • 0:出错时会返回 0
  • 一个数组:各个文件的属性信息(更多见返回值页面)

1.5. 描述

本方法会创建一个包含指定文件列表的压缩包。

若文件名是一个目录时,该目录下的所有文件和子目录都会被添加到压缩包中,并且保留原有的目录结构。

可选参数的作用之一是:修改压缩包中的文件路径或文件名,即压缩包中的目录结构可与文件系统中的不一样。 这样可以在压缩包中不暴露文件系统中的目录结构。

1.6. 示例

include_once('pclzip.lib.php');

 

$archive = new PclZip('archive.zip');

$v_list = $archive->create('file.txt,data/text.txt,folder');

if ($v_list == 0) {

die("Error : " . $archive->errorInfo(true));

}

上面示例中,创建了一个archive.zip压缩包,并将file.txt、data/text.txt文件添加到压缩包中, 压缩包内会自动创建必要的目录结构。

include_once('pclzip.lib.php');

 

$archive = new PclZip('archive.zip');

$v_list = $archive->create(

'data/file.txt,data/text.txt',

PCLZIP_OPT_REMOVE_PATH, 'data',

PCLZIP_OPT_ADD_PATH, 'install'

);

if ($v_list == 0) {

die("Error : " . $archive->errorInfo(true));

}

上面示例中,最终的效果是:

文件系统中:

  • data/file.txt
  • data/text.txt

添加到压缩包后的目录结构:

  • install/file.txt
  • install/text.txt

1. 方法:PclZip::listContent

英文原文:http://www.phpconcept.net/pclzip/user-guide/54

1.1. 概述

本方法用于列出压缩包中的文件和目录信息。

1.2. 用法

PclZip::listContent()

1.3. 返回值

可能的返回值:

  • 0:出错时会返回 0
  • 一个数组:各个文件的属性信息(更多见返回值页面)

1.4. 描述

略。

1.5. 示例

include_once('pclzip.lib.php'); $zip = new PclZip("test.zip"); if (($list = $zip->listContent()) == 0) {    die("Error : " . $zip->errorInfo(true));} for ($i=0; $i<sizeof($list); $i++) {    for(reset($list[$i]); $key = key($list[$i]); next($list[$i])) {      echo "File $i / [$key] = " . $list[$i][$key] . "";    }    echo "";}

上面示例会得到下面输出:

File 0 / [filename] = data/file1.txtFile 0 / [stored_filename] = data/file1.txtFile 0 / [size] = 53File 0 / [compressed_size] = 36File 0 / [mtime] = 1010440428File 0 / [comment] = File 0 / [folder] = 0File 0 / [index] = 0File 0 / [status] = okFile 1 / [filename] = data/file2.txtFile 1 / [stored_filename] = data/file2.txtFile 1 / [size] = 54File 1 / [compressed_size] = 53File 1 / [mtime] = 1011197724File 1 / [comment] = File 1 / [folder] = 0File 1 / [index] = 1File 1 / [status] = ok

1. 方法:PclZip::extract

英文原文:http://www.phpconcept.net/pclzip/user-guide/55

1.1. 概述

本方法用于解压压缩包中的文件和目录。

1.2. 用法

PclZip::extract([可选参数])

1.3. 参数

1.4. 参数

  • 支持的可选参数
    • PCLZIP_OPT_PATH
    • PCLZIP_OPT_REMOVE_PATH
    • PCLZIP_OPT_REMOVE_ALL_PATH
    • PCLZIP_OPT_ADD_PATH
    • PCLZIP_CB_PRE_EXTRACT
    • PCLZIP_CB_POST_EXTRACT
    • PCLZIP_OPT_SET_CHMOD
    • PCLZIP_OPT_BY_NAME
    • PCLZIP_OPT_BY_EREG
    • PCLZIP_OPT_BY_PREG
    • PCLZIP_OPT_BY_INDEX
    • PCLZIP_OPT_EXTRACT_AS_STRING
    • PCLZIP_OPT_EXTRACT_IN_OUTPUT
    • PCLZIP_OPT_REPLACE_NEWER
    • PCLZIP_OPT_STOP_ON_ERROR
    • PCLZIP_OPT_EXTRACT_DIR_RESTRICTION
    • PCLZIP_OPT_TEMP_FILE_THRESHOLD
    • PCLZIP_OPT_TEMP_FILE_ON
    • PCLZIP_OPT_TEMP_FILE_OFF

更多见可选参数页面。

1.5. 返回值

可能的返回值:

  • 0:出错时会返回 0
  • 一个数组:已解压的文件的属性信息。 注意:若只有个别文件解压失败,不会导致整个解压过程失败,并不认为是出错,但个别文件的失败状态会记录在列表中。 (更多见返回值页面)

1.6. 描述

本方法用于解压压缩包中的全部或部分文件/目录。

以下参数可用于过滤不想解压的项:

  • PCLZIP_OPT_BY_NAME
  • PCLZIP_OPT_BY_EREG
  • PCLZIP_OPT_BY_PREG
  • PCLZIP_OPT_BY_INDEX

以下参数可用于:

  • PCLZIP_OPT_PATH、PCLZIP_OPT_ADD_PATH:解压到指定的目录中
  • PCLZIP_OPT_REMOVE_ALL_PATH:删除压缩包中的所有目录结构,仅保留文件
  • PCLZIP_OPT_REMOVE_PATH:只删除部分目录结构

还有:

  • PCLZIP_OPT_EXTRACT_AS_STRING:解压文件到 PHP 字符串变量中,而不是解压到文件中

这对于小文件或者文件数较少时比较有用,如解压出 readme 文件

  • PCLZIP_OPT_EXTRACT_IN_OUTPUT:解压文件到标准输出中

1.7. 示例

require_once('pclzip.lib.php'); $archive = new PclZip('archive.zip');if ($archive->extract() == 0) {    die("Error : " . $archive->errorInfo(true));}

上面示例中,压缩包中的所有文件都解压到当前目录下。

include('pclzip.lib.php'); $archive = new PclZip('archive.zip');if ($archive->extract(                      PCLZIP_OPT_PATH, 'data',                      PCLZIP_OPT_REMOVE_PATH, 'install/release') == 0   ) {    die("Error : " . $archive->errorInfo(true));}

上面示例中,最终的效果是:

压缩包中的目录结构:

  • install/release/file.txt
  • install/release/text.txt

解压后,文件系统中:

  • data/file.txt
  • data/text.txt

1. 方法:PclZip::properties

英文原文:http://www.phpconcept.net/pclzip/user-guide/56

1.1. 概述

本方法用于获取压缩包的属性信息。

1.2. 用法

PclZip::properties()

1.3. 返回值

可能的返回值:

  • 0:出错时会返回 0
  • 一个包含压缩包属性信息的数组

1.4. 描述

获取到的压缩包属性信息包括:

  • nb:压缩包中的文件+目录数量
  • comment:压缩包的注释文字
  • status:压缩包的状态(暂只有OK状态)

1. 方法:PclZip::add

英文原文:http://www.phpconcept.net/pclzip/user-guide/57

1.1. 概述

本方法用于添加文件/目录到压缩包中。

(PclZip >= 1.1)

1.2. 用法

PclZip::add($filelist, [可选参数])

1.3. 参数

  • $filelist:文件列表,可以是以下内容
    • 一个数组,每个数组项是一个文件或目录名
    • 一个字符串:一个文件或目录名
    • 一个字符串:一堆文件或目录名,并以英文逗号,分隔
  • 支持的可选参数
    • PCLZIP_OPT_REMOVE_PATH
    • PCLZIP_OPT_REMOVE_ALL_PATH
    • PCLZIP_OPT_ADD_PATH
    • PCLZIP_CB_PRE_ADD
    • PCLZIP_CB_POST_ADD
    • PCLZIP_OPT_NO_COMPRESSION
    • PCLZIP_OPT_COMMENT
    • PCLZIP_OPT_ADD_COMMENT
    • PCLZIP_OPT_PREPEND_COMMENT
    • PCLZIP_OPT_TEMP_FILE_THRESHOLD
    • PCLZIP_OPT_TEMP_FILE_ON
    • PCLZIP_OPT_TEMP_FILE_OFF

更多见可选参数页面。

1.4. 返回值

可能的返回值:

  • 0:出错时会返回 0
  • 一个数组:各个文件的属性信息(更多见返回值页面)

1.5. 描述

本方法用于将$filelist参数中指定的文件/目录添加到压缩包中。 若是目录,则目录中的所有内容包括子目录结构都会添加到压缩包中。

若压缩包中已存在某个文件,则再次添加同名文件到压缩包时, PclZip 并不会自动覆盖已有文件,而是在压缩包内的相同目录中同时存在 2 个同名的文件。 (译注:暂未找到一个参数,可以让 PclZip 自动覆盖压缩包内已存在的文件)

可选参数可用于:

  • 修改文件在压缩包内的目录路径
  • 不压缩文件,直接添加到压缩包中
  • 为整个压缩包添加注释文字

1.6. 示例

require_once('pclzip.lib.php'); $archive = new PclZip('archive.zip');$v_list = $archive->add('file.txt,data/text.txt,folder/');if ($v_list == 0) {    die("Error : " . $archive->errorInfo(true));}

上面示例中,会将以下文件/目录添加到压缩包中:

  • txt
  • data/text.txt
  • folder/

require_once('pclzip.lib.php'); $archive = new PclZip('archive.zip');$v_list = $archive->add(    'dev/file.txt,dev/text.txt',    PCLZIP_OPT_ADD_PATH, 'install',    PCLZIP_OPT_REMOVE_PATH, 'dev');if ($v_list == 0) {    die("Error : ".$archive->errorInfo(true));}

上面示例中,最终的效果是:

文件系统中:

  • dev/file.txt
  • dev/text.txt

添加到压缩包后的目录结构:

  • install/file.txt
  • install/text.txt

1. 方法:PclZip::delete

英文原文:http://www.phpconcept.net/pclzip/user-guide/58

1.1. 概述

本方法用于删除压缩包中的全部或部分文件。

1.2. 用法

PclZip::delete([可选参数])

1.3. 参数

1.4. 参数

  • 支持的可选参数
    • PCLZIP_OPT_BY_NAME
    • PCLZIP_OPT_BY_EREG
    • PCLZIP_OPT_BY_PREG
    • PCLZIP_OPT_BY_INDEX

更多见可选参数页面。

1.5. 返回值

可能的返回值:

  • 0:出错时会返回 0
  • 一个数组:还剩在压缩包中的文件

1.6. 描述

本方法用于删除压缩包中的全部或部分文件。

以下参考可用于过滤不想删除的文件:

  • PCLZIP_OPT_BY_NAME
  • PCLZIP_OPT_BY_EREG
  • PCLZIP_OPT_BY_PREG
  • PCLZIP_OPT_BY_INDEX

1.7. 示例

require_once('pclzip.lib.php'); $archive = new PclZip('archive.zip');$v_list = $archive->delete();if ($v_list == 0) {    die("Error : " . $archive->errorInfo(true));}

上面示例中,压缩包中的所有文件都会被删除。

require_once('pclzip.lib.php');$archive = new PclZip('archive.zip');$v_list = $archive->delete(PCLZIP_OPT_BY_INDEX, '1-3,5,8-10');if ($v_list == 0) {    die("Error : " . $archive->errorInfo(true));}

上面示例中,索引在 1 至 3 和 5 至 8 范围中的文件或目录将被删除。 可通过listContent()方法获取文件的索引。

注意:索引中的目录也有自己的索引号,因此删除一个目录后,目录里面的文件不会被删除。

require_once('pclzip.lib.php'); $archive = new PclZip('archive.zip');$v_list = $archive->delete(PCLZIP_OPT_BY_EREG, 'txt$');if ($v_list == 0) {    die("Error : " . $archive->errorInfo(true));}

上面示例中,压缩包中所有txt格式的文件都被删除。

1. 方法:PclZip::merge

英文原文:http://www.phpconcept.net/pclzip/user-guide/59

1.1. 概述

本方法用于将另一个压缩包内的所有内容合并到当前压缩包中。

(PclZip >= 1.2)

1.2. 用法

PclZip::merge($archive_filename)

1.3. 参数

  • $archive_filename:将要被合并的压缩包名(被合并到当前对象的压缩包中)

1.4. 返回值

  • 0:出现错误
  • 1:合并成功

1.5. 描述

本方法用于将另一个压缩包内($archive_filename参数)的所有内容合并到当前对象的压缩包中。

合并过程中,并不会进行任何检查,如不会检查同名的文件。

本方法不是一个更新压缩包功能的函数,本方法只是一个很无脑的合并。

1. 方法:PclZip::duplicate

英文原文:http://www.phpconcept.net/pclzip/user-guide/60

1.1. 概述

本方法用于复制压缩包。

(PclZip >= 1.2)

1.2. 用法

PclZip::duplicate($archive_filename)

1.3. 参数

  • $archive_filename:将要被复制的压缩包

1.4. 返回值

  • 0:出现错误
  • 1:复制成功

1.5. 描述

本方法用于仅将参数$archive_filename中的压缩包复制为本对象刚创建的压缩包中。

若本对象已关联了一个已存在的压缩包,则会先删除这个压缩包,再复制。

1. 常见问题

英文原文:http://www.phpconcept.net/pclzip/faq

问题 1:为什么在创建一个 zip 包时,运行结束后仅留下一个空的 zip 包?

这可能是因为 PHP 中并没有启用 zlib 扩展。 PclZip 基于 zlib 进行压缩。 在 v1.1 后面的版本中会添加自动检测 zlib 是否已开启。

问题 2:为什么我不能用 WinZip 软件打开 PclZip 创建的 zip 包?

WinZip < 6.0 的版本不支持 PclZip 创建的 zip 包, WinZip >= 6.0 的版本支持。

译注:估计我们现在都很少用 WinZip 了吧,至少译者使用的 7-Zip v16 可以支持 PclZip 的 zip 包。

问题 3:在使用 PclZip 提取(创建)zip 时,PHP 在运行结束之前一直挂起(译注:即一直等待的意思),没有任何错误提示...

PclZip 的运行性能与下面两个 PHP 配置参数有关:

  • memory_limit:http://php.net/manual/zh/ini.core.php#ini.sect.resource-limits
    • memory_limit 是一次 PHP 运行中的最大内存限制,在ini中配置,默认值:8MB。PclZip 解压或压缩文件时,若碰到较大的文件时, 不可能全部在内存中操作,而会使用系统的临时文件。PclZip 是否使用临时的依据正是 PHP 的 memory_limit 参数。
  • set_time_limit:http://php.net/manual/zh/function.set-time-limit.php
    • 当 PclZip 在处理较大的文件或文件数量特别大的情况下,需要较多的时间来处理。若时间过长会因为超时而运行失败, set_time_limit 正是配置此值的参数,默认值:30s。

问题 4:为什么有时我用 PclZip 解压一个压缩包时,没解压出任何文件,也没看到任何错误提示?

PclZip 是支持错误提示的机制的,详见异常处理页面。

注意:你必须在 PclZip 方法执行完后才能通过一定方法获取到错误信息。

PclZip支持所谓的错误恢复机制,即在碰到部分错误时,并不会停止整个操作。 解压时,当压缩包内其中一个文件解压失败后,并不会终止后续其他文件的解压。

那如何知道这么多文件哪个解压成功?哪个失败(如访问权限、文件已存在、目录名冲突等原因)? 你需要了解返回的结果数组。

示例:

require_once('pclzip.lib.php'); $archive = new PclZip('archive.zip');if (($v_result_list = $archive->extract()) == 0) {    die("Error : " . $archive->errorInfo(true));} echo "<pre>";var_dump($v_result_list);echo "</pre>";

从 v2.2 开始,你可以设置在解压时只要一个文件解压失败就立即停止后续文件的解压。 对应的设置参数是PCLZIP_OPT_STOP_ON_ERROR。

require_once('pclzip.lib.php'); $archive = new PclZip('archive.zip');if (($v_result_list = $archive->extract(PCLZIP_OPT_STOP_ON_ERROR)) == 0) {    die("Error : " . $archive->errorInfo(true));} echo "<pre>";var_dump($v_result_list);echo "</pre>";

问题 5:我如何可以将当前整个目录(含子目录)压缩为一个 zip 包?

PclZip 并不支持直接输入./来指定当前目录,但你可以这么做:

require_once('pclzip.lib.php'); $archive = new PclZip('archive.zip');$v_dir = getcwd(); // or dirname(__FILE__);$v_remove = $v_dir;// 若在 Windows 中,为了支持 C: 根目录,你需要添加下面 3 行// 若在 Linux 下,则忽略下面 3 行if (substr($v_dir, 1,1) == ':') {    $v_remove = substr($v_dir, 2);} $v_list = $archive->create($v_dir, PCLZIP_OPT_REMOVE_PATH, $v_remove);if ($v_list == 0) {    die("Error : ".$archive->errorInfo(true));}

 

1. PclZip 最新消息

英文原文:http://www.phpconcept.net/pclzip/news

译注:

  • 原文中描述了最新消息的 PclZip 版本是6,而不是翻译时看到的 v2.8.2
  • 因此可忽略本页内容,因为不够新了

1.1. PclZip 2.5 新特性

PclZip v2.5 引入了一个安全功能,以及修改压缩包内的文件名的功能。 为了实现这些功能,进行了大量代码修改,以保证对压缩包内文件列表的属性的维护,而不只是全局参数的维护。

此版本虽然只允许对文件名进行修改,但代码是朝着可操作压缩包内每个文件 (如将一个字符串作为压缩包内一个新文件,修改文件的日期等) 的方向而修改的。不过暂未对解压提供类似的功能。

用户手册暂时还没更新,不过你可先看看下面关于本功能的快速示例:

$archive = new PclZip("archive.zip");$list = $archive->create(    [        [            PCLZIP_ATT_FILE_NAME => 'data/file1.txt',            PCLZIP_ATT_FILE_NEW_FULL_NAME => 'newdir/newname.txt'        ],        [            PCLZIP_ATT_FILE_NAME => 'data/file2.txt',            PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'newfilename.txt'        ],        [            PCLZIP_ATT_FILE_NAME => 'data/file3.txt'        ]    ],    PCLZIP_OPT_ADD_PATH, 'newpath',    PCLZIP_OPT_REMOVE_PATH, 'data'); if ($list == 0) {    die("ERROR : '" . $archive->errorInfo(true) . "'");}

  • PCLZIP_ATT_FILE_NEW_FULL_NAME的作用是将data/file1.txt文件修改成newdir/newname.txt, 并且此时全局参数PCLZIP_OPT_ADD_PATH和PCLZIP_OPT_REMOVE_PATH都将被忽略。
  • PCLZIP_ATT_FILE_SHORT_NAME的作用是将txt'文件修改成newfilename.txt, 之后全局参数将继续发挥作用。

GulfTech 提出 PclZip 有一个安全隐患,可在解压文件时进行恶意操作。 PclZip 在解压用户上传的 zip 压缩包时,确实可能会对服务器的系统文件进行修改。 PclZip 支持将文件解压到不同的文件夹。 在 v2.5 中添加了一个控制选项,可用于限制被解压的目录,即不能解压到指定目录之外的地方。 此参数的作用类似于 PHP 自带的open_basedir选项。

$archive = new PclZip("archive.zip");$list = $archive->extract(PCLZIP_OPT_EXTRACT_DIR_RESTRICTION, './base_dir');if ($list == 0) {    die("ERROR : '" . $archive->errorInfo(true) . "'");}

上面示例中,PclZip 会将压缩包解压到当前文件夹。若压缩包内的文件解压后是在base_dir目录之后, PclZip 会自动停止压缩,并发出异常信息。

注意:PCLZIP_OPT_EXTRACT_DIR_RESTRICTION必须是绝对路径(不能是相对路径)。 例外的是:./可以表示当前目录。

最后更新于2010年2月7日(星期日)15:19

1.2. PclZip 2.6 新特性

PclZip v2.6 引入了更多的文件层面的特性。现在你可直接将一个字符串添加到压缩包中作为一个新的文件, 而不需要先在文件系统创建文件再添加到压缩包中。

v2.6 还修复了一些已知问题。

用户手册暂时还没更新,不过你可先看看下面关于本功能的快速示例:

$archive = new PclZip("archive.zip");$v_filename = "new_file.txt";$v_content = "This is the content of file one\nHello second line";$list = $archive->create(    [        [PCLZIP_ATT_FILE_NAME => $v_filename,            PCLZIP_ATT_FILE_CONTENT => $v_content        ]    ]); if ($list == 0) {    die("ERROR : '" . $archive->errorInfo(true) . "'");}

上面示例中,$v_contenu变量中的字符串将被作为new_file.txt文件直接添加到压缩包中。

最后更新于2010年2月7日(星期日)15:24

1. 更新日志

英文原文:http://www.phpconcept.net/pclzip/release-notes

1.1. v2.8.2

  • 解压文件内容到字符串时PCLZIP_OPT_EXTRACT_AS_STRING支持PCLZIP_CB_PRE_EXTRACT、PCLZIP_CB_POST_EXTRACT回调函数,并允许在回调函数中修改解压出来的字符串。
  • 已知问题修复:
    • PCLZIP_OPT_REMOVE_ALL_PATH运行不正确问题
    • 删除eval()代码,并直接调用回调函数
    • 正确支持 64位(感谢 WordPress 团队)

1.2. v2.8.1

  • 将PCLZIP_OPT_BY_EREG参数功能修改为与PCLZIP_OPT_BY_PREG一致。 这是因为从3 开始ereg()函数将过期。 当你使用PCLZIP_OPT_BY_EREG时,PclZip 会自动替换为PCLZIP_OPT_BY_PREG。

1.3. v2.8

  • 改善解压大文件的情况,增加了使用临时文件的参数。 本功能与7 中的一致。参数包括
    • PCLZIP_OPT_TEMP_FILE_ON
    • PCLZIP_OPT_TEMP_FILE_OFF
    • PCLZIP_OPT_TEMP_FILE_THRESHOLD
  • 增加一个比例常量PCLZIP_TEMPORARY_FILE_RATIO, 用于配置自动检测是否使用临时文件的阈值。
  • 已知问题修复:
    • 删除返回的文件数组中的路径前缀.//

1.4. v2.7

  • 改善创建压缩包时包含大文件的情况:
    • PclZip 在碰到大文件时,能自动根据 PHP 内存设置来决定是否使用临时文件
    • PCLZIP_OPT_ADD_TEMP_FILE_ON强制所有文件不管大小全部使用临时文件
    • PCLZIP_OPT_ADD_TEMP_FILE_OFF则一律不使用临时文件
    • PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD可设置文件大小阈值来决定是否使用临时文件
    • 使用临时文件会比使用内存的耗时较多,下面是我笔记本上的测试:
      • 待压缩的文件大小 88MB
      • 使用内存:18s(max_execution_time=30, memory_limit=180MB)
      • 使用临时文件:23s(max_execution_time=30, memory_limit=30MB)
    • 使用time()替换mktime(),用于限制E_STRICT错误信息
    • 已知问题修复:
      • Windows 下添加文件到压缩包时,若文件路径不是默认盘符下添加不成功的问题

1.5. v2.6

  • 代码优化
  • 增加:PCLZIP_ATT_FILE_COMMENT参数,用于为单个文件添加注释(但不知有什么用处)
  • 增加:PCLZIP_ATT_FILE_CONTENT参数,用于将一个字符串直接作为文件添加到压缩包中
  • 增加:PCLZIP_ATT_FILE_MTIME参数,用于压缩包中文件的日期
  • 修复:若压缩包中的文件时间是0h0m0s,解压出来会变成当前时间的问题
  • 增加:每次操作后返回的文件列表信息中包含CRC信息
  • 增加:closedir()语句
  • 修复:当添加目录到压缩包中,并删除其路径时,此目录里面的文件会不正确地多出了一个/的问题。 因为在 Linux 中/表示根目录的意思
  • 增加:在常量定义前增加了判断语句。这允许用户重新定义常量时不需要修改 PclZip 源文件, 在后续升级 PclZip 时能更平滑。

1.6. v2.5

  • 增加:允许在添加文件/目录到压缩包时附加各自的属性信息
    • 修改文件名
    • 为每个文件分别指定
    • 修改全名(full name)
    • 修改短名(short name)
    • 兼容全局参数
  • 增加:参数:
    • PCLZIP_ATT_FILE_NAME
    • PCLZIP_ATT_FILE_NEW_SHORT_NAME
    • PCLZIP_ATT_FILE_NEW_FULL_NAME
  • 增加:错误编号:PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE
  • 增加:安全控制参数PCLZIP_OPT_EXTRACT_DIR_RESTRICTION,用于限制解压时允许解压到的目录。 因为有时恶意用户可能会通过上传一个 zip 包,由于之前 PclZip 允许解压文件到系统任意位置, 解压后替换掉系统的某些关键文件,从而造成安全问题。
  • 增加:PCLZIP_OPT_EXTRACT_DIR_RESTRICTION参数,用于限制允许解压的目录。
  • 增加:错误编号:PCLZIP_ERR_DIRECTORY_RESTRICTION
  • 修改:PclZipUtilPathInclusion()函数中以./开头的目录和路径会在其前面添加当前路径(getcwd())

1.7. v2.4

  • 代码优化:删除一些无用的pack()调用,以加快代码运行速度
  • 修复:delete()调用时应无需参数。在3 中需要参数,在 v2.4 时不再需要。
  • 修复:path_inclusion函数中,当路径包含多个../../时会导致错误。
  • 增加:对magic_quotes_runtime配置参数的检查。若开启,当正确运行时,PclZip 会禁用它,并重设会原来的值。 这样可解决很多格式不正确的压缩错误。
  • 修复:当压缩前的文件大小与压缩后一样时不能正确解压的问题
  • 修复:当设置了PCLZIP_OPT_REMOVE_ALL_PATH参数后,不再新建目录的问题
  • 代码优化:正确关闭opendir()打开的东西,这在循环中能更好处理.和..。

1.8. v2.3

  • 修复:当赋值0xFE49FFE0给一个变量时,PHP4 与 PHP5 运行结果不一致的问题

1.9. v2.2

  • 尝试:开发新参数PCLZIP_OPT_CRYPT,但停止开发了。原因: 在加密或解密时,我需要对两个长整数(比long还要长)进行相乘, 但 PHP 并不支持此功能,即使使用了bcmath的函数也没用。 我现在还没找到解决方案。。。
  • 修复:目录最后忘了添加/的问题
  • 增加:检查文件是否已被加密。可返回状态unsupported_encryption(不支持的加密方式)及 错误编号:PCLZIP_ERR_UNSUPPORTED_ENCRYPTION
  • 修复:本地文件头信息中的不正确字段version need to extract
  • 增加:private 方法privCheckFileHeaders(),用于检查本地和中心文件的头信息。 PclZip 现在支持purpose bit flag bit 3(译注:参考zip 格式规范) purpose bit flag bit 3允许用户在本地文件头信息中不包含这些字段:大小、压缩后大小、crc。
  • 增加:PCLZIP_ERR_UNSUPPORTED_COMPRESSION错误编码,用于表示检测到 PclZip 不支持的的压缩算法。 PclZip 仅支持(deflate)算法。在2 之前,PclZip 不会检测压缩包中的压缩算法, 在 v2.2 及之后会进行压缩算法检测,若发现不支持的压缩算法,会返回unsupported_compression状态和PCLZIP_ERR_UNSUPPORTED_COMPRESSION错误码。
  • 增加:PCLZIP_OPT_STOP_ON_ERROR参数,用于在解压时碰到第一个解压错误时就立即停止后续所有的解压 (默认情况下,PclZip 解压碰到错误时仅在返回文件列表属性值标记错误状态,并继续进行后续其他文件的解压)。 可能的错误包括:
    • 已存在同名目录
    • 已存在同名的且时间更新的文件
    • 已存在受保护的文件
  • 增加:PCLZIP_OPT_REPLACE_NEWER参数。默认情况下,PclZip 解压时遇到文件系统已存在同名文件, 但文件系统中的文件时间更老的话,PclZip 会自动用解压出来的文件替换掉文件系统的老文件; 若文件系统的文件时间更新,PclZip 不会替换该文件。本参数用于强制替换文件系统的已存在文件,不管时间新旧。
  • 改善:PclZipUtilOption()函数
  • 增加:支持在压缩包最后附带尾部字节。在2 之前,PclZip 会检测中心目录应在压缩包的最后位置。 Crypt 在加密或解密 zip 包时,会在解密完毕时在文件最后添加0 bytes。PclZip 现在支持此功能。

1.10. v2.1

  • 增加:PCLZIP_OPT_EXTRACT_IN_OUTPUT参数,用于直接解压文件输出到标准输出中
  • 增加:文件注释描述参数
    • PCLZIP_OPT_COMMENT:创建文件注释,若已存在注释,则替换原有注释
    • PCLZIP_OPT_ADD_COMMENT:创建文件注释,若已存在注释,则追加到已有注释后面
    • PCLZIP_OPT_PREPEND_COMMENT:在已有文件注释前增加注释
  • 增加:在解压过程的回调函数中终止后续解压的功能。只需在回调函数中返回2即可停止后续解压。 对于解压前的回调函数,会在解压当前文件前停止;对于解压后的回调函数,会在后续文件停止。
  • 增加:合并两个压缩包时,会自动合并注释,并以空格分隔。
  • 修复:删除压缩包内所有文件时,并没删除的问题。
  • 修复:若文件名就叫0,会导致 PclZip 创建压缩包或添加属性时意外终止。

1.11. v2.0

注意:v2.0 与 v1.x 存在不兼容,你若从 v1.x 升级到 v2.0,你需要修改你原有的代码,请认真往下看。

  • 增加:可按压缩包内的索引、名字、正则表达式来删除压缩包中的文件/目录。 对应到方法是delete(),支持下面参数:
    • PCLZIP_OPT_BY_INDEX
    • PCLZIP_OPT_BY_NAME
    • PCLZIP_OPT_BY_EREG
    • PCLZIP_OPT_BY_PREG
  • 增加:支持按正则表达式解压压缩包内的文件/目录。 使用方式是:extract()+PCLZIP_OPT_BY_EREG(或 PCLZIP_OPT_BY_PREG )+正则表达式。
  • 增加:支持使用extract()方法按压缩包内的文件索引来解压文件。这是extractByIndex()改良版。
  • 增加:支持按名字解压压缩包内的文件/目录。对应方法是:
    • 方法:extract()
    • 参数:PCLZIP_OPT_BY_NAME
    • 参数值:一个文件名字符串或,一个文件名列表数组
    • 若想解压某个目录的全部内容,应在文件名参数的最后带上/
  • 增加:PCLZIP_OPT_NO_COMPRESSION参数,用于不压缩直接添加文件到压缩包中。
  • 增加:PCLZIP_OPT_EXTRACT_AS_STRING参数,用于直接解压文件到字符串中,而非解压到文件系统或临时文件中。
  • 增加:PCLZIP_SEPARATOR常量,用于设置单字符串中表示多个文件名时的分隔符,默认值是英文逗号,, 而不是以前版本中说的空格。(注意:此常量的值与x 的不兼容!)
  • 优化:通过不使用临时文件(译注:改用内存),提高解压或压缩时的性能。
  • 增加:对空文件名的检测,这在被删除的路径与被 zip 压缩的目录是一样的时候会有用。 目录本身不会被 zip 压缩(['status'] = filtered),压缩的是目录中的内容。
  • 优化:对 Windows 路径的更好支持(感谢 manus@manusfreedom.com 的帮助)
  • 修复:压缩包已存在,且大小为 0 时,add()方法会出错的问题。
  • 修改:删除OS_WINDOWS常量,改用php_uname()函数
  • 增加:解压文件时,支持指定索引的范围
  • 优化:修改内部的目录管理(更好的支持内部标记)

1.12. v1.3.1

  • 修复:解压过程中,执行回调函数时的相关问题

1.13. v1.3

  • 删除:重复的include检查,现在使用的是include_once()、require_once()。
  • 修改:错误处理机制:
    • 删除对外部错误库处理的使用
    • 之前的PclError()函数被修改为内部的等价的函数
    • 若修改PCLZIP_ERROR_EXTERNAL,你依然可使用之前的库
    • 引入错误标号常量,避免之前的纯整数看不懂,这会极大方便后续的维护
    • 引入对应的错误处理函数:errorCode()、errorName()、errorInfo()
  • 删除:废弃函数调用中直接传引用
  • 添加:为extract()、extractByIndex()、create()、add()方法的调用增加变量参数,而非固定的参数数量。
  • 增加:PCLZIP_OPT_REMOVE_ALL_PATH参数,用于在解压或压缩时去除所有的文件路径,无需指定任何路径值。 支持的方法:
    • extract()
    • extractByIndex()
    • create()
    • add()
  • 增加:PCLZIP_OPT_SET_CHMOD参数,用于在解压完毕后,对解压出来的文件进行权限修改(基于 PHP chmod())。 支持的方法:
    • extract()
    • extractByIndex()
  • 增加:回调函数机制。 使用回调函数,你可进行一些相关的操作。 支持回调函数的方法:
    • add()
    • extract()
    • extractByIndex()
    • create()
    • 回调函数参数包括:
      • PCLZIP_CB_PRE_EXTRACT:在每个文件解压出来前被调用。用户可以在修改文件名、跳过不解压当前文件 (会被标记为skipped)等。
      • PCLZIP_CB_POST_EXTRACT:在每个文件解压出来后被调用。这里没有什么可以被修改的。
      • PCLZIP_CB_PRE_ADD:在每个文件被添加到压缩包前被调用。用户可以在修改文件名、跳过不添加当前文件 (会被标记为skipped)等。
      • PCLZIP_CB_POST_ADD:在每个文件被添加到压缩包后被调用。这里没有什么可以被修改的。
    • 增加:会增加两个状态标记到返回的文件属性列表中:
      • skipped:回调函数中主动设置为跳过时
      • filename_too_long:文件名太长时(此时文件不会被添加到压缩包)
    • 增加:PclZipUtilPathInclusion()函数,用于检查目录的路径。
    • 增加:在某些操作前,检查压缩包中的文件是否已存在(如 list 操作)
    • 增加:初始化头部数组中的字段index。当操作方法没有明确设置此字段值时,默认为-1。

1.14. v1.2

  • 增加:复制方法(duplicate())
  • 增加:合并方法(merge()),用于将另一个压缩包内的所有内容合并到当前对象的压缩包中。 合并过程中,并不会进行任何检查,如不会检查同名的文件。
  • 优化:对中心目录结尾的搜索

1.15. v1.1.2

译注:上面链接已失效

  • 增加:PCLZIP_TEMPORARY_DIR常量,用于指定 PclZip 使用的临时文件夹。
  • 完善:rename()函数,此函数在不同的文件系统中可能会出错,将使用copy()+unlink()替代。
  • 修复:WinZip 不能对 PclZip 生成的压缩包内的文件进行删除或增加的问题。

1.16. v1.1.1

  • 修复:不做任何压缩直接添加文件到压缩包后,不能成功解压的问题

1.17. v1.1

  • 增加:PclZip::Add()方法
  • 增加:PclZip::ExtractByIndex()方法
  • 增加:PclZip::DeleteByIndex()方法
  • 修复:在某些场景下,使用绝对路径压缩文件时出错的问题

1.18. v1.0.1

  • 修复:当文件大于PCLZIP_READ_BLOCK_SIZE(默认:1024 字节)设置的值时会压缩出错的问题

 

 类似资料: