从Slim Framework下载文件时出现问题

时间:2014-05-10 09:27:08

标签: php download slim

我想通过Slim Framework下载文件(我之所以使用Slim Framework是因为我想编写一个简单的REST API)。我发现这篇文章: Download file from Slim Framework 2.4和此帖:http://help.slimframework.com/discussions/questions/359-file-download。我按照这个方法。这是我的代码:

$app->get('/download/:id', 'authenticate', function($id) use ($app)
{    
    $log = '../download/'.$id.'/myfile.zip';

    $res = $app->response()->headers();
    $res['Content-Description'] = 'File Transfer';
    $res['Content-Type'] = 'application/octet-stream';
    $res['Content-Disposition'] ='attachment; filename=' . basename($log);
    $res['Content-Transfer-Encoding'] = 'binary';
    $res['Expires'] = '0';
    $res['Cache-Control'] = 'must-revalidate';
    $res['Pragma'] = 'public';
    $res['Content-Length'] = filesize($log);

    readfile($log);    

    // NOTE: 
//        $response = array();
//        $response["error"] = false;
//        echoRespnse(200, $response);

});

我正在使用Google Chrome的Advanced Rest Client应用程序进行测试。问题是文件下载后浏览器挂起。如果我在源代码中注释了NOTE部分,浏览器就不会再挂起了。但是我得到了一个"意想不到的令牌P"错误。

有人可以帮忙吗?感谢。

4 个答案:

答案 0 :(得分:1)

在此尝试解决方案:PHP readfile() adding extra bytes to downloaded file

你没有调用ob_clean,flush和exit。

问题可能是由于文件内容的其余部分输出了额外的字符。

答案 1 :(得分:1)

对于Slim 3,我有点挣扎。 我在Slim 3.0中苦苦挣扎。 我尝试了类似下面的内容,并在屏幕上显示了pdf二进制文件。

$header['Content-Description']  = 'File Transfer';
$header['Content-Disposition'] = 'attachment; filename="' .basename("$file") . '"';

// ...
$response   = $response->withHeader($header);

为了使其正常工作,您需要使用$response->withHeader()设置键/值对。它就像一个魅力。例如:

$response   = $response->withHeader('Content-Type', 'application/pdf');
$response   = $response->withHeader('Content-Description', 'File Transfer');
$response   = $response->withHeader('Content-Disposition', 'attachment; filename="' .basename("$file") . '"');
$response   = $response->withHeader('Content-Transfer-Encoding', 'binary');
$response   = $response->withHeader('Expires', '0');
$response   = $response->withHeader('Cache-Control', 'must-revalidate');
$response   = $response->withHeader('Pragma', 'public');
$response   = $response->withHeader('Content-Length', filesize($file));

答案 2 :(得分:0)

也许它有点迟了但你可以使用这个包来获得苗条的http文件响应: https://github.com/mhndev/slim-file-response

答案 3 :(得分:-1)

上面的解决方案适合您吗?这是我的代码,它只是将晦涩的字符直接输出到浏览器窗口中:

$app->get('/file/:fileid', function($fileid) use ($app)
{
    $zip = new ZipArchive();
    $zipname = "zipfile3.zip"; // Zip name
    $zip->open($zipname,  ZipArchive::CREATE);
    $files = array ( "sprecher_inserts_en_VB.doc" );

    foreach ($files as $file) {
        $path = "uploads/".$file;
        if(file_exists($path)){
            $zip->addFromString(basename($path),  file_get_contents($path));  
        }
        else{
            echo"file does not exist";
        }
    }
    $zip->close();
    // after that, the zip file is on the server and valid when downloaded manually (e.g. by entering its URL directly)

    $res = $app->response()->headers();
    $res['Content-Description'] = 'File Transfer';
    $res['Content-Type'] = 'application/octet-stream';
    $res['Content-Disposition'] ='attachment; filename=' . basename($zipname);
    $res['Content-Transfer-Encoding'] = 'binary';
    $res['Expires'] = '0';
    $res['Cache-Control'] = 'must-revalidate';
    $res['Pragma'] = 'public';
    $res['Content-Length'] = filesize($zipname);

    ob_clean();    
    flush();
    readfile($zipname);    
    exit();
});

浏览器窗口中的输出如下,无论如何都没有加载下载文件的对话框: Output of the code shown above