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
Pdo Prepared Statements With Wildcards
File_Get_Contents(): PHP_Network_Getaddresses: Getaddrinfo Failed: Name or Service Not Known
Convert Latin1 Characters on a Utf8 Table into Utf8
Insert - Number of Bind Variables Doesn't Match Number of Fields in Prepared Statement
Laravel Certificate Verification Errors When Sending Tls Email
Difference Between 2 Dates in Seconds
How to Get the Classname from a Static Call in an Extended PHP Class
Checking to See If One Array'S Elements Are in Another Array in PHP
Rebase Array Keys After Unsetting Elements
How to Locate the PHP.Ini File (Xampp)
Compare Multiple Values in PHP
How to Run a PHP Script Inside a HTML File
Using PHP'S Swiftmailer With Gmail
Generating Cryptographically Secure Tokens