ZipArchive php 获取损坏或空的 zip

Posted

技术标签:

【中文标题】ZipArchive php 获取损坏或空的 zip【英文标题】:Getting corrupted or empty zip by ZipArchive php 【发布时间】:2013-02-09 22:01:45 【问题描述】:

我通过以下代码下载了 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);
    

【问题讨论】:

它给了我错误。这意味着没有创建 $zipname 的目录。但是我没有收到“篮子里什么都没有”的消息,而是下载了一个 zip 文件。 【参考方案1】:

尝试在 $zip-&gt;close(); 之前获取完整的文件路径和名称

$filename = $zip->filename;

在读取文件和获取文件大小时使用它而不是$zipname

【讨论】:

@Pony 也检查一下.. 仍然遇到同样的问题。我认为该文件的目录没有被创建。我还检查了 'var_dump($filename)' 是否显示确切路径。 你在调用$zip-&gt;close()之前分配了这个变量吗? 工作就像一个魅力!谢谢:)【参考方案2】:

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

记住:您不能将 URL 传递到 $zip-&gt;addfile(),您需要您的实际文件。

【讨论】:

【参考方案3】:

即使这个问题已经解决了,我也会发布我发现如何创建损坏的 zip 的内容:

制作 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);
    

【讨论】:

删除 echo 和 print_r 语句对我有用...谢谢 :)【参考方案4】:

即使原来的问题已经解决了,我也加入了这个帖子,因为我花了几个小时解决了一个类似的问题。

在执行 $zip->close() 时,文件都需要存在,无论何时使用 $zip->addFile() 添加它们。

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

【讨论】:

【参考方案5】:

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

【讨论】:

【参考方案6】:

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

经过一些研究和测试,我发现我需要做的就是添加文件名(我不知道为什么它在旧服务器上工作)作为第二个参数:$zip-&gt;addFile($value, $zipname); // $zipname in this case

我遇到的另一个问题是我的 memory_limit 太低了

希望这会有所帮助!

【讨论】:

【参考方案7】:

就我而言,问题归结为在 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]);

【讨论】:

以上是关于ZipArchive php 获取损坏或空的 zip的主要内容,如果未能解决你的问题,请参考以下文章

我使用 PHP 的 ZipArchive 创建的 .zip 存档在 Windows 10 上已损坏/无效

php ZipArchive 多文件打包下载

查询不等于 null 或空的地方

过滤 obj[array[@]] 为 nil 或空的数组

TP测试查询数据库字段为null或空的字段

TP测试查询数据库字段为null或空的字段