7

我正在通过以下代码下载 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);
    }
}
4

7 回答 7

5

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

$filename = $zip->filename;

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

于 2013-02-09T22:21:41.887 回答
3

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

请记住:您不能将 URL 传递给$zip->addfile(),您需要您的实际文件。

于 2013-02-10T12:29:26.930 回答
1

即使这个问题很难解决,我也会发布我发现如何创建损坏的 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);
    }
}
于 2013-08-26T10:45:42.247 回答
1

即使最初的问题已经解决,因为我刚刚花了几个小时来解决类似的问题,所以添加到这个线程。

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

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

于 2017-03-02T15:33:47.913 回答
0

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

于 2017-12-28T11:44:54.873 回答
0

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

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

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

希望这可以帮助!

于 2019-10-01T07:29:16.103 回答
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]);
于 2020-02-28T11:56:10.480 回答