修剪框架 - 创建将返回可下载文件流的路由

时间:2018-04-13 04:15:53

标签: php csv slim-3

我在index.php

中创建了以下Slim Framework路线

$app->get('/generatecsv', ShippingCSVGenerator::class . ':generateShippingCSV');

函数generateShippingCSV()被正确调用,但是我想返回一个流,该流应该可以通过JS在任何可能需要的视图中下载。

public function generateShippingCSV()
{
    // ...some code here... //
    $out = fopen('dispatch.csv', 'w');
    foreach ($CSVArray as $fields) {
        fputcsv($out, $fields);
    }
    $stream = new \GuzzleHttp\Psr7\LazyOpenStream('dispatch.csv', 'r');
    $response->withBody($stream);
    return $response;
}

上面的函数正确创建了CSV,但是我不想创建文件 - 我想要返回文件流。

*编辑*

添加:

return $response->withHeader('Content-Type', 'application/force-download')
    ->withBody($stream);

...只要通过浏览器访问路径,就会使文件可用,但我更愿意返回一个流,而不是生成并返回一个物理文件。

1 个答案:

答案 0 :(得分:2)

有很多方法可以实现这一目标。例如:

  1. 扩展Slim Slim\Http\RequestBody class

    <?php
    
    use Slim\Http\RequestBody;
    
    class CsvRequestBody extends RequestBody
    {
         public writeCsv(array $CSVArray) 
         {
              $this->rewind();
              foreach ($CSVArray as $fields) {
                  fputcsv($this->stream, $fields);
              }      
         } 
    }
    

    然后在您的代码中输出响应

    $csvBody = new CsvRequestBody();
    $scvBody->writeCsv($CSVArray);
    return $response->withHeader('Content-Type', 'application/force-download')
                    ->withBody($csvBody);
    
  2. 将数据写入php://temp,将其读取到变量,然后将其写入响应正文。

    $out = fopen('php://temp', 'w');
    foreach ($CSVArray as $fields) {
        fputcsv($out, $fields);
    }
    rewind($out);
    $csvData = stream_get_contents($out);
    fclose($out);
    
    $response->getBody()->rewind();
    $response->getBody()->write($csvData);
    return $response->withHeader('Content-Type', 'application/force-download');