antanas_sepikas
antanas_sepikas

Reputation: 5704

File response from zip

Here's what I am trying to do: I have created zip archive using ZipArchive class with multiple files inside, what I need to do now, open archive, read single file and download or open it in browser.

Since I am using symfony2 framework, if it were a regular file, I could do something like this:

case 'open':
    $response = new BinaryFileResponse($filepath);
    $response->headers->set('Content-type', mime_content_type($filepath));
    $response->setContentDisposition(
        ResponseHeaderBag::DISPOSITION_INLINE,
        $filename
    );
    return $response;
case 'save':
    $response = new BinaryFileResponse($filepath);
    $response->headers->set('Content-type', mime_content_type($filepath));
    $response->setContentDisposition(
        ResponseHeaderBag::DISPOSITION_ATTACHMENT,
        $filename
    );
    return $response;

But since the file isn't in any directory I can pass it to BinaryFileResponse class because it accepts only string path to the file or SplFileInfo object, and not the file contents.

I found following post which gave me idea to create SplFileObject from file contents and then pass it to BinaryFileResponse class as SplFileInfo object since SplFileObject extends SplFileInfo, so here's what I'v done:

$tmp = 'php://temp';
$file = new \SplFileObject($tmp, 'w+');
$file->fwrite($filecontents);

And then pass $file to BinaryFileResponse class, but it throws error: The file "php://temp" does not exist. I don't know if I am on the right way of doing something like this, and if so what I am missing.

In any case what I wan't to achieve is to serve file from archive in 2 different ways: 1. downlaod, 2.Open in browser.

PS. Those files are PDF format. And I can open them if I create response object and set it's content to that of a file from archive, but then I can't make it to download directly.

Sorry if it's confusing, and thanks for any help in advance.

Upvotes: 1

Views: 1332

Answers (1)

antanas_sepikas
antanas_sepikas

Reputation: 5704

What I eventually came up with:

//1. Extract file to chosen directory
$zip = new \ZipArchive();
if ($zip->open('file/path/file.zip') {
    $zip->extractTo('chosen/directory', array('filename_in_zip_archive.ext'));
    $zip->close();
}

//2. Put file in response
$response = new Response(file_get_contents('chosen/directory/filename_in_zip_archive.ext'));
$mime = new \finfo(FILEINFO_MIME_TYPE);
$response->headers->set('Content-type', $mime->file('chosen/directory/filename_in_zip_archive.ext'));

//3. logic to open or download file
case 'open':
    $response->headers->makeDisposition(ResponseHeaderBag::DISPOSITION_INLINE, 'filename_in_zip_archive.ext');
case 'save': 
    $response->headers->makeDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'filename_in_zip_archive.ext');


//4. After file has been put to response, delete local file copy
if (file_exists('chosen/directory/filename_in_zip_archive.ext')) {
    unlink('chosen/directory/filename_in_zip_archive.ext');
}

//5. Return response with file
return $response;

Upvotes: 1

Related Questions