通过ZipArchive php获取损坏或空拉链

时间:2013-02-09 22:01:46

标签: php zip ziparchive

我通过以下代码下载zip文件,没有任何错误,但下载的zip文件为空或已损坏,大小总是大约200字节。 即我无法打开该zip文件。 ZipArchive :: getStatusString()也显示"没有错误"

代码是:

public function getzip(){
    global $config;
    $files=array();
    if(isset($_COOKIE['hashes'])){
        $hashes=explode(',',$_COOKIE['hashes']);
        for ($i=0; $i <count($hashes); $i++) {
            array_push($files,$config["domain"]."/download/".$hashes[$i]); 
        }
    }
    if(count($files)){
        $zipname='basket.zip';
        $zip = new ZipArchive;
        $zip->open($zipname,ZipArchive::CREATE);
        foreach ($files as $key=>$value ) {
            $zip->addFile($value);
        }
        $status=$zip->getStatusString();
        $zip->close();

    if(!$zipname)
    {
        echo "Nothing in Basket";
    }
    else
    {   header('Content-Description: File Transfer');
        header('Content-Type: application/zip');
        header('Content-Disposition:attachment; filename='.basename($zipname));
        header('Content-Length:'.filesize($zipname));
        readfile($zipname);
    }
}

7 个答案:

答案 0 :(得分:5)

尝试在$zip->close();

之前获取完整的文件路径和名称
$filename = $zip->filename;

在读取文件并获取文件大小

时使用它代替$zipname

答案 1 :(得分:3)

这是我最好的猜测。这里出现的问题是,在您的数组$files中,您存储的值可能不是文件的实际路径。

请记住:您无法将网址传递到$zip->addfile(),您需要实际的文件。

答案 2 :(得分:1)

即使很难解决这个问题,我也会发布我发现如何创建损坏的拉链:

制作zip存档时,通常会使用echo / print_r命令进行调试。如果您不清除它们,输出zip文件将会损坏。

基于问题的示例:

public function getzip(){
    global $config;
    $files=array();
    if(isset($_COOKIE['hashes'])){
        $hashes=explode(',',$_COOKIE['hashes']);
        for ($i=0; $i <count($hashes); $i++) {
            array_push($files,$config["domain"]."/download/".$hashes[$i]); 
        }
    }
    if(count($files)){
        $zipname='basket.zip';
        $zip = new ZipArchive;
        $zip->open($zipname,ZipArchive::CREATE);
        foreach ($files as $key=>$value ) {
            $zip->addFile($value);
        }
        $status=$zip->getStatusString();
        $zip->close();

    if(!$zipname)
    {
        echo "Nothing in Basket";
    }
    else
    {   
        // to fix your corrupt zip file, remove this line.
        echo 'THIS IS AN EXAMPLE DEBUG: ' . $zipname;
        header('Content-Description: File Transfer');
        header('Content-Type: application/zip');
        header('Content-Disposition:attachment; filename='.basename($zipname));
        header('Content-Length:'.filesize($zipname));
        readfile($zipname);
    }
}

答案 3 :(得分:1)

即使最初的问题已经解决,因为我只花了几个小时来处理类似的问题,所以添加到这个帖子。

事实证明,在执行$ zip-&gt; close()时,所有文件都需要存在,无论您何时使用$ zip-&gt; addFile()添加它们。

因此,如果您创建临时文件,将它们添加到zip中,然后在使用close()之前将其删除,最终可能会出现空/损坏的存档。

答案 4 :(得分:0)

我通过将代码移动到我想要添加到Zip存档的文件所在的同一文件夹来解决了同样的问题。

答案 5 :(得分:0)

这可能对OP没有用,但是在更改虚拟服务器时遇到了这个问题。我不知道服务器设置中发生了什么变化,但是zip开始生成空zip。

经过研究和测试,我发现我需要做的就是添加文件名(我不知道为什么它在旧服务器上工作)作为第二个参数:
Application context instantiating error

我遇到的另一个问题是$zip->addFile($value, $zipname); // $zipname in this case太低了

希望这会有所帮助!

答案 6 :(得分:0)

就我而言,问题归结于在ZipArchive::addGlob()方法的add_path选项中传递值'/':

    $zipArchive->addGlob($tmpFolder . DIRECTORY_SEPARATOR ."*", 
                         0, 
                         ['add_path' => '/', 'remove_all_path' => true]);

删除即可为我解决问题:

    $zipArchive->addGlob($tmpFolder . DIRECTORY_SEPARATOR ."*", 
                         0, 
                         ['remove_all_path' => true]);