Excellent comment by @Kevin. Drupal core doesn't use StreamedResponse, but as always the Webform module is a good resource for examples, which also shows the difference between viewing and downloading the streamed result:
/modules/contrib/webform/modules/webform_submission_export_import/src/Controller/WebformSubmissionExportImportController.php
/**
* Returns the Webform submission export example CSV view.
*/
public function view() {
return $this->createResponse(FALSE);
}
/**
* Returns the Webform submission export example CSV download.
*/
public function download() {
return $this->createResponse(TRUE);
}
/**
* Create a response containing submission CSV example.
*
* @param bool $download
* TRUE is response should be downloaded.
*
* @return \Symfony\Component\HttpFoundation\Response
* A response containing submission CSV example.
*/
protected function createResponse($download = FALSE) {
$webform = $this->importer->getWebform();
// From: http://obtao.com/blog/2013/12/export-data-to-a-csv-file-with-symfony/
$response = new StreamedResponse(function () {
$handle = fopen('php://output', 'r+');
$header = $this->importer->exportHeader();
fputcsv($handle, $header);
for ($i = 1; $i <= 3; $i++) {
$webform_submission = $this->generateSubmission($i);
$record = $this->importer->exportSubmission($webform_submission);
fputcsv($handle, $record);
}
fclose($handle);
});
$response->headers->set('Content-Type', $download ? 'text/csv' : 'text/plain');
$response->headers->set('Content-Disposition', ($download ? 'attachment' : 'inline') . '; filename=' . $webform->id() . '.csv');
return $response;
}
When testing this module you won't see much of a streaming effect when viewing the result in the browser because of the buffering enabled in most web servers. You need much higher numbers of items, like $i <= 3000
, to fill up the buffers and get a streaming effect for a few seconds.