找回密码
 新建账号

[PHP] PHP ZipArchive 的坑

[复制链接]
php 发表于 2015/12/17 07:03 | 显示全部楼层 |阅读模式
PHP ZipArchive 有很多坑,一不小心就会让你掉进坑里,让看似正常的程序得不到预期的结果。
  • ZipArchive 创建或者打开的 zip 文档,在 ZipArchive::close() 这个方法被调用之前,只是在操作一个临时的文件,只有在调用了 close() 方法之后,压缩文档才会真正的开始完成文件的操作和保存工作,如果没有在代码里面明确调用 close() 这个方法,PHP 会在代码最后自动去调用。
    比如很多人遇到的问题,先将一个文件压缩进 zip 文档中,然后将文件删除,如以下代码,当 addFile() 调用完成以后,虽然函数返回了 true,但是这个时候 PHP 并没有真的地将文件加入到压缩文件中,而只是对添加文件到压缩包这件事情做了一个“登记”,直到 $za->close() 被调用的时候才会真正地去添加文件到压缩包中,然而很遗憾的是,如下代码中,在执行实际添加文件的操作的时候,文件已经被删除了,因此程序会出错,无论之前对压缩文件做过多少操作,都回到了最初的状态,因为压缩文件没有创建成功,如果该压缩文件早前已经存在,文件不会有任何变化。参见:PHP压缩文件夹和子目录为zip文件 使用内置ZipArchive类实现
    1. <?php
    2.         $za = new ZipArchive();
    3.         $za->open('./xc.zip', ZipArchive::CREATE|ZipArchive::OVERWRITE);
    4.         $file = './notes.txt';
    5.         if( true === $za->addFile($file)){
    6.                 unlink($file);
    7.         }
    8.         if(!$za->close()){
    9.                 echo 'failure.';
    10.         }
    11. ?>
    复制代码

  • ZipArchive::addFile($file, $saveAs) 如果 $file 是一个目录的路径,会导致程序出错,无论你之前做过多少操作,直接回到解放前,文件不会创建成功,如果该压缩文件早前已经存在,文件不会有任何变化,更气人的是,如果目录真实存在的的话,它的返回值还是 true.
    因此,如果通过 scandir() 之类的函数获取目录的文件列表的话,一定要记得把返回的文件列表中的子目录给删除掉,只保留子目录里面的文件。
    参见:ZipArchive addFile 传递的参数是文件夹时将导致整个代码失效
  • 如果 ZipArchive open() 了一个不存在的文件,并且你使用了 ZipArchive::OVERWRITE ,你经过一翻折腾,最终没有文件写入到压缩文件中,那么你会遇到 “ZipArchive::close(): Can't remove file: No such file or directory” 这个错误,要破解这个问题,要么不要用 ZipArchive::OVERWRITE,自己用代码去检查要创建的文件是否已经存在,如果存在就删除它;要么每次 open() 一个不存在的文件后,先向压缩文件中先写入一个无关紧要的文件。

手机版|轻松E站

GMT+8, 2024/3/29 19:39

快速回复 返回顶部 返回列表