I build a shop with Zend Framework 2 where you can by digital stuff like music and download them.
Now i have a the following situation:
I have a controller that controlls all downloads. I start to download a large file and it takes several minutes until the download is finished. While i am downloading, i can't browse in my shop with the same browser that I use for the download.
Is it possible to configure zend 2, so that i still can browse my website while downloading or is this impossible due to the fact that i execute the same script by launching the application througb the index.php file?
Update
$response = new Stream();
$response->setStream(fopen($finalFilePath, 'r'));
$response->setStatusCode(200);
$response->setStreamName(basename($finalFilePath));
$headers = new Headers();
$headerArr = array(
'Content-Disposition' => 'attachment; filename="' . basename($finalFilePath) .'"',
'Content-Type' => 'application/octet-stream',
'Content-Transfer-Encoding' => 'Binary',
'Content-Length' => filesize($finalFilePath),
);
$headers->addHeaders($headerArr);
$response->setHeaders($headers);
return $response;
Found a solution. It has something to do with sessions !
just call
session_write_close();
before the "return".
Related
I am trying download files in controller but in the console I see only really bunch of weird characters instead of download box. I am following this topic Symfony2 - Force file download.
Don't know what is going on... trying to find simplest solution.
Here is my code:
$response = new Response(file_get_contents($file->realPath), 200, array(
'Content-Type' => $file->mimeType,
'Content-Length' => filesize($file->realPath),
'Content-Disposition' => 'attachment; filename=' . $file->name,
));
$response->send();
I've even tried to use the most basic example with header() and readfile().
Does my server need special config or something? Cheers.
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.
In the controller you can use $this->file(...)
The file needs full filesystem path with file to download
return $this->file('/home/website/upload/'.$someFile)
Also it is possible to define another name when downloading:
return $this->file('/home/website/upload/'.$someFile, 'MyFile.pdf');
I am trying download files in controller but in the console I see only really bunch of weird characters instead of download box. I am following this topic Symfony2 - Force file download.
Don't know what is going on... trying to find simplest solution.
Here is my code:
$response = new Response(file_get_contents($file->realPath), 200, array(
'Content-Type' => $file->mimeType,
'Content-Length' => filesize($file->realPath),
'Content-Disposition' => 'attachment; filename=' . $file->name,
));
$response->send();
I've even tried to use the most basic example with header() and readfile().
Does my server need special config or something? Cheers.
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.
In the controller you can use $this->file(...)
The file needs full filesystem path with file to download
return $this->file('/home/website/upload/'.$someFile)
Also it is possible to define another name when downloading:
return $this->file('/home/website/upload/'.$someFile, 'MyFile.pdf');
I am missing something in the KnpSnappy Bundle docs. :( How do I save my pdf to the server using Symfony and KnpSnappy. I don't want my pdf to download to the browser. I want it to save to the server. Please help! Thanks so much.
Server Path: $pdfFolder = $_SERVER['DOCUMENT_ROOT'].'/symfonydev/app/Resources/account_assets/'.$account_id.'/pdf/';
return new Response(
$this->get('knp_snappy.pdf')->getOutputFromHtml($content),
200,
array(
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'attachment; filename="'.$pdfFolder.''.strtotime('now').'.pdf"'
)
);
As you can see from documentation you need to use another function:
$this->get('knp_snappy.pdf')->generateFromHtml($content, $pdfFolder . time() . '.pdf';
As you can see I replaced your strtotime('now') by time(). It will be faster.
This line generates the PDF...
$this->get('knp_snappy.pdf')->getOutputFromHtml($content)
So you could probably just use file_put_contents to write the result of getOutputFromHtml($content) to the file system.
I'm trying to download a file when a user clicks on download link.
In Controller:
$response = new Response();
$response->headers->set('Content-type', 'application/octect-stream');
$response->headers->set('Content-Disposition', sprintf('attachment; filename="%s"', $filename));
$response->headers->set('Content-Length', filesize($filename));
return $response;
This is opening the dialog box to save the file, but it says the file is 0 bytes.
And changing it to:
$response = new Response();
$response->headers->set('Content-type', 'application/octect-stream');
$response->headers->set('Content-Disposition', sprintf('attachment; filename="%s"', $filename));
$response->headers->set('Content-Length', filesize($filename));
$response->headers->set('Content-Transfer-Encoding', 'binary');
$response->setContent(readfile($filename));
return $response;
I get a bunch of weird characters instead of the file download dialog box.
Finally, switching the "setContent" line to:
$response->setContent(file_get_contents($filename));
It returns a PHP error:
Fatal error: Allowed memory size...
Any clues on how to achieve this?
I've done it before in PHP (wihtout MVC), but I don't know what can be missing to do it through Symfony2...
Maybe the solution is setting the memory_limit in PHP.INI, but I guess it´s not the best practice...
The most comfortable solution is
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
$response = new BinaryFileResponse($file);
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT);
return $response;
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;
You shouldn't use PHP for downloading files because it's a task for an Apache or Nginx server. Best option is to use X-Accel-Redirect (in case of Nginx) / X-Sendfile (in case of Apache) headers for file downloading.
Following action snippet can be used with configured Nginx to download files from Symfony2:
return new Response('', 200, array('X-Accel-Redirect' => $filename));
UPD1: Code for apache with configured mod_xsendfile:
return new Response('', 200, array(
'X-Sendfile' => $filename,
'Content-type' => 'application/octet-stream',
'Content-Disposition' => sprintf('attachment; filename="%s"', $filename))
);
As of Symfony 3.2 you can use the file() controller helper which is a shortcut for creating a BinaryFileResponse as mentioned in a previous answer:
public function fileAction()
{
// send the file contents and force the browser to download it
return $this->file('/path/to/some_file.pdf');
}
Don't know if it can help but it's application/octet-stream not application/octect-stream
+1 for alexander response.
But if you can't use X-Sendfile, you should use the BinaryFileResponse added in the 2.2: http://symfony.com/doc/current/components/http_foundation/introduction.html#serving-files
In my project the result is
$response = new \Symfony\Component\HttpFoundation\BinaryFileResponse($dir .DIRECTORY_SEPARATOR. $zipName);
$d = $response->headers->makeDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT,
$zipName
);
$response->headers->set('Content-Disposition', $d);
return $response;
For those who don't have the option of setting headers:
The download attribute may help depending on which browsers you need to support:
<a href="{file url}" download>
or
<a href="{file url}" download="{a different file name}">
This is not supported in all legacy browsers. See this page for browser support:
https://www.w3schools.com/tags/att_a_download.asp
I am using amazon S3 service with PHP by using this API
https://github.com/tpyo/amazon-s3-php-class
I am passing the url to client like this
https://domain.s3.amazonaws.com/bucket/filename_11052011111924.zip?AWSAccessKeyId=myaccesskey&Expires=1305311393&Signature=mysignature
So when the client clicks or paste the URL into browser , the file downloaded with the name of filename_11052011111924.zip.But I stored my original filename in DB.
So is it possible to download when passing the URL alone to the client and download with original file name.I am not sure whether this will help me.
Content-Disposition: attachment; filename=FILENAME.EXT
Content-Type: application/octet-stream
If you set the headers that you listed on your file when you upload it to S3, you will be able to download the file with the original filename. (you can also set these on existing files in S3 - see the AWS docs)
I'm not sure if your library supports this but you can do it with the AWS S3 SDK.
Something like (I don't know php so check the syntax):
// Instantiate the class
$s3 = new AmazonS3();
$response = $s3->create_object('bucket', 'filename_11052011111924.zip', array(
'fileUpload' => 'filename.zip',
'contentType' => 'application/octet-stream',
'headers' => array( // raw headers
'Content-Disposition' => 'attachment; filename=filename.zip',
),
));
Update
You can also adjust certain headers each time you generate a new url. See http://docs.amazonwebservices.com/AWSSDKforPHP/latest/#m=AmazonS3/get_object_url
$url = $s3->get_object_url('bucket', 'filename_11052011111924.zip', '5 minutes', array(
'response' => array(
'Content-Disposition' => 'attachment; filename=filename.zip'
)
));
I don't think that will work (I never tried it though). You might need to download the file to your server first, later use headers, once it is completed (or after sometime later with some bot or cron) you can delete the file(s).
This approach will be using your bandwidth.
Yes, you can tell to AWS how output file must be named:
Note: we encode file name!
$filename = "Here we can have some utf8 chars.ext";
$outputFileName = '=?UTF-8?B?' . base64_encode($filename) . '?=';
$url = $s3->get_object_url(
'bucket_name',
'path_to_the_file.ext',
'5 minutes',
array(
'response' => array(
'content-disposition' => 'attachment;' . " filename=\"" . $outputFileName . "\";")
)
)
);