Skip to content

Instantly share code, notes, and snippets.

@zuzuleinen
Last active October 3, 2024 17:01
Show Gist options
  • Save zuzuleinen/6db61b09465e9bc8a7ea to your computer and use it in GitHub Desktop.
Save zuzuleinen/6db61b09465e9bc8a7ea to your computer and use it in GitHub Desktop.
CSV Response in Symfony controller action
<?php
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class CsvController extends Controller
{
/**
* Get a CSV file from an array
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function csvAction()
{
$list = array(
//these are the columns
array('Firstname', 'Lastname',),
//these are the rows
array('Andrei', 'Boar'),
array('John', 'Doe')
);
$fp = fopen('php://output', 'w');
foreach ($list as $fields) {
fputcsv($fp, $fields);
}
$response = new Response();
$response->headers->set('Content-Type', 'text/csv');
//it's gonna output in a testing.csv file
$response->headers->set('Content-Disposition', 'attachment; filename="testing.csv"');
return $response;
}
}
@Nyholm
Copy link

Nyholm commented Jan 20, 2021

Correct. But using php://temp allow you to be smart, ie by using Symfony\Component\HttpFoundation\StreamedResponse.

@nacholibre
Copy link

Agree

@d1823
Copy link

d1823 commented Feb 3, 2022

It's also worth to explain why one shouldn't write to php://output in this case. That stream is the same one as the one used by echo or print statements. Obviously, you can also access it via ob_* functions. The thing is - you've got no idea what's in it or who's going to write to it. I've had a case, where using it caused the Content-Type of a response to randomly change between text/csv and text/html. In other words - weird things happened!

Switching to anything else, in my case to php://temp (thanks Nyholm!), did the trick.

@justin-oh
Copy link

A bit late, but there is a class called CsvEncoder. You can do something like this:

use Symfony\Component\Serializer\Encoder\CsvEncoder;

$csvEncoder = new CsvEncoder();

$data = [];

foreach ($people as $person) {
    $data[] = [
        'First Name' => $person->getFirstName(),
        'Last Name' => $person->getLastName(),
    ];
}

$csv = $csvEncoder->encode($data, 'csv');

The array keys of each element in $data are the headers. You can change the header order by doing something like this:

$headers = ['Last Name', 'First Name'];

$csv = $csvEncoder->encode($data, 'csv', [
    'csv_headers' => $headers,
]);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment