SlimPHP应用程序不下载文件

时间:2017-02-15 07:58:46

标签: php http browser http-headers slim

我正在尝试使用SlimPHP下载文件,但它似乎对我不起作用。

以下是我所做的路线:

    $backendApp->post('/export', function ($request, $response, $args) {
        $emails = $this->orginization->exportEmails();
        $exportFile = $this->file->writeEmailExport($emails, 'AllEmails.csv');

        $fh = fopen($exportFile, "r");
        $stream = new \Slim\Http\Stream($fh);

        $response = $response->withHeader('Content-Type', 'application/octet-stream')
            ->withHeader('Content-Description', 'File Transfer')
            ->withHeader('Content-Disposition', 'attachment; filename="' . basename($exportFile) . '"')
            ->withHeader('Content-Length', filesize($exportFile))
            ->withBody($stream);

        return $response;
    });

我知道$ exportFile是一个有效的PHP流媒体资源,因为文件的内容会在响应中返回,我只需要为用户触发浏览器文件下载功能。

这些是响应中出现的标题:

Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection:close
Content-Description:File Transfer
Content-Disposition:attachment; filename="AllEmails.csv"
Content-Length:267
Content-Type:application/octet-stream
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Host:localhost:8080
Pragma:no-cache
X-Powered-By:PHP/5.6.15

有什么事情能让我在这里做错了吗?我可以看到文件的内容在响应选项卡中返回,所以我知道我正在获取文件的内容,我只需要提示用户下载该文件。

1 个答案:

答案 0 :(得分:1)

与此相关,但是您正在调用此代码:

$app = new \Slim\App($config);

$app->get("/", function ($request, $response, $args) {

    $response->write(
        <<<EOT
<form method="POST" action="/export">
<input type="submit" value="Download">
</form>
EOT
    );

    return $response;
});

$app->post('/export', function ($request, $response, $args) {
    $exportFile = __DIR__ . '/../test_file.txt';

    $fh = fopen($exportFile, "r");
    $stream = new \Slim\Http\Stream($fh);

    $response = $response->withHeader('Content-Type', 'application/octet-stream')
        ->withHeader('Content-Description', 'File Transfer')
        ->withHeader('Content-Disposition', 'attachment; filename="' . basename($exportFile) . '"')
        ->withHeader('Content-Length', filesize($exportFile))
        ->withBody($stream);

    return $response;
});

您说您可以在响应标签中看到信息。这是否意味着您通过JavaScript触发此操作?如果是这样,那么浏览器将把文件发送回JS而不是用户。如果要显示文件下载对话框,则提供一个表单(如您所希望的POST),其上有一个按钮供用户单击。