Laravel:使用StreamedResponse生成和下载CSV文件会产生ERR_INVALID_RESPONSE

时间:2017-12-04 14:57:26

标签: php laravel symfony

我有一个像这样的控制器方法:

use Symfony\Component\HttpFoundation\StreamedResponse;

public function downloadTransactions($type)
{
    $this->authorize('download', Invoice::class);

    $filename = 'invoices-' . strtolower($type) . '.csv';

    $response = new StreamedResponse(function() {

        Invoice::generateTransactionsCsv($type);

    }, 200, [
        'Content-Type' => 'text/csv',
        'Content-Disposition' => 'attachment; filename="' . $filename . '"',
    ]);

    return $response;

}

然后在我的Invoice模型中填充文件:

public static function generateTransactionsCsv($type = null)
{
    // Open output stream
    $handle = fopen('php://output', 'w');

    // Add CSV headers
    fputcsv($handle, [
        'ID',
        'REF',
        'DESCRIPTION',
        'DATE',
        'AMOUNT',
    ]);

    // Close the output stream
    fclose($handle);
}

但我在Chrome中获得ERR_INVALID_RESPONSE,但我认为浏览器并不重要。我已经检查了类似的问题,建议安装zip扩展名,但我已经安装了它。在本地使用PHP 7.1。还尝试查看日志,但似乎没有任何东西(在本地使用代客)。

如果我将逻辑从模型移动到控制器然后它工作正常但我上面的例子被简化为csv的标题行,实际上,还有更多它,所以我想保持如果可能,模型中的逻辑。

我也尝试在控制器中打开和关闭文件句柄并将其传递给模型,但这也不起作用。

1 个答案:

答案 0 :(得分:0)

看起来是因为$type变量未正确传递:

$response = new StreamedResponse(function() use ($type) {
    ....
}

感谢Safari能够解决这个问题,它下载了一个带有Laravel错误跟踪的csv,这很奇怪,我认为它与Chrome没什么不同。