在PHP 5.1上创建和下载ZipArchive失败,适用于PHP 5.4

时间:2015-04-27 22:49:15

标签: php ziparchive

当尝试添加嵌套在另一个添加的空目录中的新空目录时,以下类失败并出现ZipArchive错误23 - “已删除条目”。例如:

dir1:
    file1
    file2
    ...

工作得很好,但有点像:

dir1:
    dir2:
        file1
        ...
    file1
    file1
    ...
尝试添加dir1/dir2

将失败。

下载班级

class Downloader {

    var $path, $tmp, $zip, $txt, $selected;

    function __construct($selected) {
        global $webroot;

        $this->path = $webroot.'downloads/';
        $this->tmp = tempnam('../tmp', 'dln');
        $this->zip = new ZipArchive();
        $this->zip->open($this->tmp, ZipArchive::OVERWRITE);
        $this->txt = '';
        $this->selected = $selected;
    }

    public function incl_file($name) {
        $this->zip->addFile($this->path.$name, $name);
    }

    public function incl_dir($name) {
        $this->zip->addEmptyDir($name);
        $files = new DirectoryIterator($this->path.$name.'/');
        foreach ($files as $file) {
            if (!$file->isDot()) {
                if ($file->isDir()) {
                    $this->incl_dir($name.'/'.$file->getFilename());
                } else {
                    $this->incl_file($name.'/'.$file->getFilename());
                }
            }
        }
    }

    public function download($downloadObj) {
        $selected = preg_split('/,/', $this->selected);
        foreach ($selected as $name) {
            $this->txt .= file_get_contents($this->path.$name.'.snip');

            foreach ($downloadObj->files as $file) {
                if ($name == $file->name) {
                    // check to see if there are files to include
                    if (strlen($file->incl_files) > 0) {
                        // if so, get include directories
                        $incl_dirs = preg_split('/,/', $file->incl_dir);
                        // iterate include directories
                        foreach ($incl_dirs as $dir) {
                            // get include file groups
                            $incl_file_groups = preg_split('/,/', $file->incl_files);
                            // iterate include file groups
                            foreach ($incl_file_groups as $group) {
                                // get individual include files
                                $incl_files = preg_split('/\|/', $group);
                                // iterate individual include files
                                foreach ($incl_files as $f) {
                                    // check to see if all files in include dir should be inserted
                                    if ($f == '*') {
                                        $this->incl_dir($dir);
                                    } else {
                                        $path = '';
                                        if ($dir == "/") {
                                            $path = $f;
                                        } else {
                                            $path .= $dir.'/'.$f;
                                        }
                                        $this->incl_file($path);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        $this->txt = file_get_contents($this->path.'header.inc').$this->txt.file_get_contents($this->path.'footer.inc');
        $this->zip->addFromString('DownloadTemplate.xml', $this->txt);
        $this->zip->close();
        $filename = 'MyDownload.zip';
        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
        header('Last-Modified: ' . gmdate('D,d M YH:i:s') . ' GMT');
        header('Cache-Control: no-cache, must-revalidate');
        header('Pragma: no-cache');
        header('Content-type: application/zip');
        header('Content-Disposition: attachment; filename='.$filename);
        header('Content-Transfer-Encoding: binary');
        readfile($this->tmp);
        unlink($this->tmp);
    }
}

2 个答案:

答案 0 :(得分:0)

PHP之前zip已通过different means安装。因此,当您更新到5.4时,您可能使用PHP编译或打印了zip扩展,并且在5.1上没有它

答案 1 :(得分:0)

经过大量调试和测试不同的选项后,事实证明问题出在addEmptyDir()的调用中。由于某些原因,我仍然没有找到答案,调用无法在Zip中添加目录。但是,我随后发现调用是完全没必要的,因为addFile()在给定相对路径名称(例如'dir1/file1')时会创建必要的目录。知道了这一点,我刚刚删除了对addEmptyDir()的调用,并且能够正确生成包含相应目录的zip文件。