php 关于使用 ZipArchive 生成ZIP文件,下载解压出现多级目录问题

sanlanlan 2018-10-11 标签: PHP 浏览:2555 评论:0

使用php ZipArchive 来进行在线生成zip 文件,是一个常见的应用。

但,在使用的时候,出现一个问题,就是在线生成的ZIP文件,下载解压下来之后,出现多级目录的情况,

比如解压后出现:var/local/data/zip 类似这样

这样不是想要的结果。


解决这个问题的关键是:



addFile

这个函数。


bool ZipArchive::addFile ( string $filename [, string $localname = NULL [, int $start = 0 [, int$length = 0 ]]] )


$localname 如果不配置的话,默认是  $filename 的路径


$oZip->addFile ( $file_name, " " . basename ( $file_name ) )

如果配置成这样,可以解决多级目录的问题,但是会出现,文件都在根目录下,原先的目录层级消失了。


所以应该这样做,

$filename 使用绝对路径
$localname 使用 $filename 对应的相对路径


代码如下:


    function generateZip($file_list, $filename)
    {
        $zip = new \ZipArchive();
        foreach ($file_list as $abs_path) {
            if (is_dir($abs_path)) {
                if ($zip->open($filename, \ZipArchive::CREATE) === true) {
                    addDirectoryToZip($abs_path, $zip);
                }
            }
            if (is_file($abs_path)) {
                if ($zip->open($filename, \ZipArchive::CREATE) === true) {
                    $relative_path = str_replace(__DIR__.'/../../data/', '../../../../', $abs_path);        //相对路径
                    $zip->addFile($abs_path, $relative_path);
                }
            }
            $zip->close();
        }
    }

    function addDirectoryToZip($abs_path, $zip)
    {
        $handler = opendir($abs_path);
        while (($filename = readdir($handler)) !== false) {
            if ($filename != "." && $filename != "..") {
                if (is_dir($abs_path."/".$filename)) {
                    addDirectoryToZip($abs_path."/".$filename, $zip);
                } else {
                    $relative_path = str_replace(__DIR__.'/../../data/', '../../../../', $abs_path);        //相对路径
                    $zip->addFile($abs_path."/".$filename, $relative_path);
                }
            }
        }

        @closedir($abs_path);
    }


ps:更多详细信息,请参照官网。



下载文件


如果是以 Response 形式返回


    public function downloadFile($file, $filename='')
    {
        $filename = $filename ? $filename : basename($file);
        $filetype = strtolower(trim(substr(strrchr($filename, '.'), 1)));

        ini_set("memory_limit", "1024M");
        ob_end_clean();
        @set_time_limit(0);

        $response = new Response();
        $response->headers->set('Cache-Control', 'must-revalidate, post-check=0, pre-check=0');
        $response->headers->set('Expires', gmdate('D, d M Y H:i:s') . ' GMT');
        $response->headers->set('Content-Encoding', 'none');
        $response->headers->set('Content-type', $filetype);
        $response->headers->set('Content-Disposition', 'attachment; filename=' . $filename);
        $response->headers->set('Content-length', filesize($file));
        $response->sendHeaders();
        $response->setContent(file_get_contents($file)); //
        $response->send(); //

        return $response;
    }


如果直接返回

public function fileDown($file, $filename = '') {
        if (!$data && !is_file($file))
            exit;
        $filename = $filename ? $filename : basename($file);
        $$filetype = strtolower(trim(substr(strrchr($filename, '.'), 1)));

       

        ini_set("memory_limit", "1024M");
        ob_end_clean();
        @set_time_limit(0);
        if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false) {
            header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
            header('Pragma: public');
        } else {
            header('Pragma: no-cache');
        }
        header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
        header('Content-Encoding: none');
        header('Content-Length: ' . filesize($file));
        header('Content-Disposition: attachment; filename=' . $filename);
        header('Content-Type: ' . $filetype);
        readfile($file);
        exit;
    }


本文相关标签: php ZipArchive zip addFile 多级目录 文件下载

发表评论: