【问题标题】:Slim 3 Framework how to download fileSlim 3 框架如何下载文件
【发布时间】:2016-06-29 21:32:09
【问题描述】:

我正在尝试使用 Slim 3 PHP 框架下载文件。 Slim 2 相当简单,我相信 Slim 3 也是如此,但我就是不明白。

任何帮助将不胜感激。 基于此处的文档:http://www.slimframework.com/docs/objects/response.html 我从这里添加了包: https://github.com/guzzle/psr7

所以我的代码此时看起来像:

$app->get('/worksheet/download/{filename}', function ($request, $response, $args) {

    error_log("__________________________");

    $fileName = $args['filename'];
    error_log($fileName);
    $newStream = new \GuzzleHttp\Psr7\LazyOpenStream($fileName, 'r');


    $newResponse = $response->withHeader('Content-type', 'application/octet-stream')
        ->withHeader('Content-Description', 'File Transfer')
        ->withHeader('Content-Disposition', 'attachment; filename=' . basename($fileName))
        ->withHeader('Content-Transfer-Encoding', 'binary')
        ->withHeader('Expires', '0')
        ->withHeader('Cache-Control', 'must-revalidate')
        ->withHeader('Pragma', 'public')
        ->withHeader('Content-Length', filesize($fileName))
        ->withBody($newStream);
return($newResponse);
});

【问题讨论】:

  • 应该注意,我尝试下载的文件位于文档根目录之外。否则我只会直接链接到文件。

标签: php download slim slim-3


【解决方案1】:

我正在使用来自 php 的readfile method

$file = 'monkey.gif';

if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment;filename="'.basename($file).'"');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    readfile($file);
    exit;
}

这个例子来自上面的链接,也许你可以尝试用 Slim Response 对象和 WithHeader 方法来实现这些 headers。

{filename}[{filename}] 的区别在于第二种形式,文件名是可选的。

$app->get('/my[/{optional}]/route', function($req, $res, $args) {});
$app->get('/myother/{not_optional}/route', function($req, $res, $args) {});

在此示例中,您可以访问 /my/route,因为不需要参数,但您无法访问 /myother/route,因为您需要 not_optional 参数。
Slim documentation有更多信息。

编辑

$app->get('/download', function($req, $res, $args) {
    $file = 'public_html/images/back2.jpg';
    $response = $res->withHeader('Content-Description', 'File Transfer')
   ->withHeader('Content-Type', 'application/octet-stream')
   ->withHeader('Content-Disposition', 'attachment;filename="'.basename($file).'"')
   ->withHeader('Expires', '0')
   ->withHeader('Cache-Control', 'must-revalidate')
   ->withHeader('Pragma', 'public')
   ->withHeader('Content-Length', filesize($file));

readfile($file);
return $response;
});

这段代码对我来说很好用,它是用 Slim 3.3.0 制作的

【讨论】:

  • legomolina,您是否在 SLIM 3 框架内使用此代码?另外,感谢您对Required Vs的提醒。可选。
  • 不,有几次我需要实现这段代码,但当我这样做时,我已经脱离了 Slim。我认为它应该适用于 Slim
  • 对于大文件,你最终会达到 PHP 的内存限制,因为 Slim 使用 ob_get_clean 包装了一个路由方法。
【解决方案2】:
$app->get('/test-download', function($request, Slim\Http\Response $response, $args) {
    $file = __DIR__ . '/2.csv';
    $fh = fopen($file, 'rb');

    $stream = new \Slim\Http\Stream($fh); // create a stream instance for the response body

    return $response->withHeader('Content-Type', 'application/force-download')
                    ->withHeader('Content-Type', 'application/octet-stream')
                    ->withHeader('Content-Type', 'application/download')
                    ->withHeader('Content-Description', 'File Transfer')
                    ->withHeader('Content-Transfer-Encoding', 'binary')
                    ->withHeader('Content-Disposition', 'attachment; filename="' . basename($file) . '"')
                    ->withHeader('Expires', '0')
                    ->withHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
                    ->withHeader('Pragma', 'public')
                    ->withBody($stream); // all stream contents will be sent to the response
});

【讨论】:

  • 谢谢。你对关闭文件指针有什么建议吗?
  • try { //上面的代码从 $file= 到 return 语句 } catch(\Exception $e) { $this->logger->error("发送文件时出错 $file", ["异常"=>$e]); } 最后 { $stream->close(); }
猜你喜欢
  • 1970-01-01
  • 2016-05-17
  • 1970-01-01
  • 2016-08-19
  • 2016-06-16
  • 1970-01-01
  • 2016-01-19
  • 2014-09-10
  • 1970-01-01
相关资源
最近更新 更多