Symfony2 - Force File Download

Symfony2 - Force file download

I finally solved this without X-SendFile (which is probably the best practice). Anyway, for those who can't get X-Sendfile apache module to work (shared hosting), here's a solution:

// Generate response
$response = new Response();

// Set headers
$response->headers->set('Cache-Control', 'private');
$response->headers->set('Content-type', mime_content_type($filename));
$response->headers->set('Content-Disposition', 'attachment; filename="' . basename($filename) . '";');
$response->headers->set('Content-length', filesize($filename));

// Send headers before outputting anything
$response->sendHeaders();

$response->setContent(file_get_contents($filename));

return $response;

Symfony2 - generate csv from string and force file download

You did not specify content type. My download example:

$dispositionHeader = $response->headers->makeDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT,
$filename . '.csv'
);

$response->headers->set('Content-Type', 'text/csv; charset=utf-8');
$response->headers->set('Pragma', 'public');
$response->headers->set('Cache-Control', 'maxage=1');
$response->headers->set('Content-Disposition', $dispositionHeader);

Symfony: Force file download encoding not working

If you want to force download a file and preserve its original contents, it's better to use BinaryFileResponse instead of the regular Response. It's doing everything that you're doing manually in your code, and then some. Your controller code can look just like this:

public function exportNewsAction() {
$path = $this->get('kernel')->getRootDir().'/Resources/files/csvExport';
$csvPath = $path."/News-Item-".$now.".csv";
$response = new BinaryFileResponse($csvPath);
$response->setContentDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT,
basename($csvPath)
);

return $response;
}

Also, how are you opening the downloaded CSV? If you're using MS Excel, there's a big chance that it won't detect the encoding properly. Try opening the file with some text editor, like Notepad++, see how the characters look like and which encoding it detects.

symfony - download files

Instead of rebuilding that kind of response, you could use Symfony's built-inBinaryFileResponse.

use Symfony\Component\HttpFoundation\BinaryFileResponse;

$response = new BinaryFileResponse($file);

Please take also a look in the documentation about serving files.

Symfony2 : How to force download multiple images in one zip file with Ajax

did u add use

use ZipArchive;

in your controller and also try this one

$response = new Response();

// Set headers

$response->headers->set('Cache-Control', 'private');
$response->headers->set('Content-type', mime_content_type($filename));
$response->headers->set('Content-Disposition', 'attachment; filename="' . basename($filename) . '"');
$response->headers->set('Content-length', filesize($filename));

// Send headers before outputting anything
$response->sendHeaders();

$response->setContent(file_get_contents($filename));

if still strict with matter then try to remove the sendHeaders

Symfony Force Download Response breaks text files

Finally figured it out. Posting it here in case someone, somewhere has a similar problem and finds it useful:

So. It turns out that the problematic line was this:

$response-sendHeaders()

For binary files, this line is critical in making it work. Text files don't need it though and will in fact break like seen above. I have not found out exactly 'why' it behaves like this. But the solution was to simply check for whether or not the requested file is a text file or not. (with a build in exception for .html files, but thats more of a optional feature / quirk of the project and can thus be safely ignored)

This is what the function looks like now and its working fine:

public function getForceDownloadResponse($file_path, $file_name){
$file_info = finfo_open(FILEINFO_MIME_TYPE);
$mime_type = finfo_file($file_info, $file_path.$file_name);
$text = (substr(finfo_file($file_info, $file_path.$file_name), 0, 4) == 'text') ? 1 : 0;
finfo_close($file_info);

$response = new Response();
$response->headers->set('Cache-Control', 'private');
$response->headers->set('Content-type', $mime_type);
$response->headers->set('Content-Disposition', 'attachment; filename="' . $file_name . '"');
$response->headers->set('Content-length', filesize($file_path.$file_name));

if(!$text || $mime_type == 'text/html'){
$response->sendHeaders();
}

$response->setContent(readfile($file_path.$file_name));

return $response;
}

Since I still don't know what actually caused the different behaviors its not as safe and solid as I'd like it to be, but it does the job just fine so far.

How to force download a .csv file in Symfony 2, using Response object?

Here is a minimal example that works just fine in production:

class MyController
public function myAction()

$response = $this->render('ZaysoAreaBundle:Admin:Team/list.csv.php',$tplData);

$response->headers->set('Content-Type', 'text/csv');
$response->headers->set('Content-Disposition', 'attachment; filename="teams.csv"');

return $response;

You can replace the render call with new response and response->setContent if you like.

Your comment about no return statement inside a controller is puzzling. Controllers return a response. Let the framework take care of sending the stuff to the browser.



Related Topics



Leave a reply



Submit