LargeTuna
LargeTuna

Reputation: 2824

Symfony php zip file has zero bytes when downloaded

I am attempting to create & download a zip file using symfony2. When I create the zip file everything looks great. When I view the zip file on the server everything looks great. When I download the zip file it has zero bytes. What is going wrong with my response?

    // Return response to the server...
    $response = new Response();
    $response->setStatusCode(200);
    $response->headers->set('Content-Type', 'application/zip');
    $response->headers->set('Content-Disposition', 'attachment; filename="'.$zipName.'"');
    $response->headers->set('Content-Length', filesize($zipFile));
    return $response;

Upvotes: 2

Views: 1019

Answers (3)

JesusTheHun
JesusTheHun

Reputation: 1237

What you do is send a response containing headers. Only headers. You need to send the file too.

Look at Symfony documentation : http://symfony.com/doc/current/components/http_foundation/introduction.html#serving-files

In vanilla PHP you want to :

header('Content-Description: File Transfer');
header('Content-Transfer-Encoding: binary');
header("Content-Disposition: attachment; filename=$filename");

And then read the file to the output.

$handle = fopen('myfile.zip', 'r');    

while(!eof($handle)) {
echo fread($handle, 1024);
}

fclose($handle);

With the documentation , you easily can find the solution ;)

EDIT :

Beware of the size of your file. Using file_get_contents or stream_get_contents you will load the entire file into PHP's memory. If the file is big, you can reach php's memory limit and end up with a fatal error. Using a loop with fread, you only load chunks of 1024 bytes into memory.

EDIT 2 :

I had some time to test, this works perfectly with large files :

$response = new BinaryFileResponse($zipFile);
$response->setStatusCode(200);
$response->headers->set('Content-Type', 'application/zip');
$response->headers->set('Content-Disposition', 'attachment; filename="'.basename($zipFile).'"');
$response->headers->set('Content-Length', filesize($zipFile));

return $response;

Hope this fully answer your question.

Upvotes: 2

MouradK
MouradK

Reputation: 1567

Near to the goal !

  // Return response to the server...
    $response = new Response();
    $response->setContent(file_get_contents($zipFile));
    $response->setStatusCode(200);
    $response->headers->set('Content-Type', 'application/zip');
    $response->headers->set('Content-Disposition', 'attachment; filename="'.$zipName.'"');
    $response->headers->set('Content-Length', filesize($zipFile));
    return $response;

Or simplier

return new Response(
            file_get_contents($zipFile),
            200,
            [
                'Content-Type'        => 'what you want here',
                'Content-Disposition' => 'attachment; filename="'.$fileName.'"',
            ]
        );

Upvotes: 1

Matteo
Matteo

Reputation: 39410

Probably you miss the file content.

Try with

$response = new Response(file_get_contents($zipFile));

instead of

$response = new Response();

Hope this help

Upvotes: 2

Related Questions