【问题标题】:ZIP file won't download and acts weird with phpZIP 文件不会下载并且对 php 的行为很奇怪
【发布时间】:2016-08-12 11:24:50
【问题描述】:

我正在 laravel 中开发一个系统,以制作一个充满照片的 zip 文件,然后下载。

我决定我真的不想为此使用库(这是必要的),所以我必须使用纯 php。我的控制器代码:

public function downloadPictures()
{
    $pictures = Input::get('photos');
    $file_paths = array();

    foreach ($pictures as $picture_id) {
         $path = $this->photos->getFilepath($picture_id, 'original');
         array_push($file_paths, $path);
    }

    $zip = new ZipArchive;
    $zip->open('slike.zip', ZipArchive::CREATE);

    foreach ($file_paths as $file) {
        $content = file_get_contents($file);
        $zip->addFromString(basename($file), $content);
    }

    header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: private",false);
    header('Content-type: application/zip');
    header('Content-Disposition: attachment; filename="'.basename($zip->filename).'"');

    echo var_dump($zip);
    echo basename($zip->filename);

    $zip->close();

    echo var_dump($zip);
    echo basename($zip->filename);
}

现在有了代码的第一部分,我可以 100% 自信地说我得到了正确的图片路径(即在 //if (file_exists($file_paths ... ) 评论上方,我通过打印出来并使用 file_exists 来确保)

但随后事情开始变得不稳定。

首先:当我打开 zip 时,我测试的 numFiles 说里面已经有 4 个文件,我不知道为什么。

其次:当我在 js 前端打印来自这个控制器函数的响应时(在控制器 var_dump($zip) 中使用 echo)我得到了 zip 文件属性.. name+ numFile+4(由于某种原因 +4),但是当我 @ 987654325@我无法访问properites echo zip属性为空。

第三:重定向标头,我以两种方式使用:在我关闭 $zip 之前和之后(目前它们在关闭之前)没有做任何事情.. 他们应该在浏览器中生成一个下载表单,是不是不是吗?

如果有人可以帮助我,我会非常感激。我需要在星期天做这个,我现在已经摆弄了大约 8 个小时。(这是我第一次这样做)。我已经做了很多谷歌搜索,它适用于其他人。我在 nginx,php v5.6 上使用 ununtu,我安装了 php zip 扩展,我正在 ubuntu mozilla 浏览器上对其进行本地测试。

更新:它在 chrome 中也不起作用,所以这不是 Firefox 的问题。

【问题讨论】:

    标签: php laravel php-zip-archive


    【解决方案1】:

    试试这个:

    public function downloadPictures()
    {
        $pictures = Input::get('photos');
        $file_paths = array();
    
        foreach ($pictures as $picture_id) {
            $path = $this->photos->getFilepath($picture_id, 'original');
            array_push($file_paths, $path);
        }
    
        $zip = new ZipArchive;
        $zipname = 'silke.zip';
        $zip->open($zipname, ZipArchive::CREATE);
    
        foreach ($file_paths as $file) {
            $content = file_get_contents($file);
            $zip->addFromString(basename($file), $content);
        }
    
        header("HTTP/1.1 200 OK");
        header("Pragma: public");
        header("Expires: 0");
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Cache-Control: private",false);
        header('Content-type: application/zip');
        header('Content-Disposition: attachment; filename="'.$zipname.'"');
        header('Content-Length: ' . filesize($zipname));
    
        $zip->close();
        readfile($zipname);
    }
    

    最重要的是Content-Lengthreadfileline。

    不要回显其他任何内容,它会破坏下载。

    更新:更独立的测试:

    $testData = array(
        'test1.txt' => 'Test1',
        'test2.txt' => 'Test2',
        'test3.txt' => 'Test3',
        'test4.txt' => 'Test4',
    );
    
    $zip = new ZipArchive;
    $zipname = 'slike.zip';
    $zip->open($zipname, ZipArchive::CREATE);
    
    foreach ($testData as $filename => $content) {
        $zip->addFromString($filename, $content);
    }
    
    header("HTTP/1.1 200 OK");
    header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: private",false);
    header('Content-Type: application/force-download');
    header('Content-Disposition: attachment; filename="'.$zipname.'"');
    header('Content-Length: ' . filesize($zipname));
    
    $zip->close();
    readfile($zipname);
    

    还有header('Content-Type: application/force-download');

    【讨论】:

    • 感谢您的输入,我猜 $zip 是空白的,因为它已关闭,但文件仍然存在(也许?)尽管解决方案似乎不起作用,奇怪的是 .. readfile( ) 产生这个postimg.org/image/k4rzlo2ud 弹出窗口,也许它必须做一些事情让它不起作用?
    • 是否有可能在 ubuntu/mozilla/server 上阻止下载/浏览器响应/下载提示/与服务器配置有关?浏览器配置/ubuntu 配置?
    • 尝试将我添加的新的独立测试直接作为单个 php 文件运行。在我的环境中,这对我来说效果很好。
    • 我猜你使用的是独立的 php 环境还是什么?也许我的问题是我在 laravel php 环境中有这个?
    • 你可以在没有 laravel 的独立 php 脚本中尝试这个,看看它是否正常工作?也许 laravel 默认会发送更多数据,而您必须以某种方式阻止它?
    猜你喜欢
    • 2021-08-09
    • 1970-01-01
    • 2014-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多