ZIP文件不会下载,并且使用php

时间:2016-08-12 11:24:50

标签: php laravel php-zip-archive

我正在使用laravel系统制作一个装满照片的拉链并随后下载。

我觉得我真的不想为此使用库(这是必要的),所以我必须使用普通的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 ... )评论之上,我确保打印出来并使用{{1 }})

但事情开始变得不稳定。

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

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

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

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

更新:它也没有在chrome中工作,所以它不是firefoxes问题。

1 个答案:

答案 0 :(得分:0)

试试这个:

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-Lengthreadfile行。

不要回复任何其他内容,否则会破坏下载。

更新:更自我测试的测试:

$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');