web-dev-qa-db-ja.com

Symfony2はZipファイルを作成してダウンロードします

いくつかのファイルをアップロードするアプリケーションが1つあり、Zipファイルとして圧縮してダウンロードできます。

エクスポートアクション:

public function exportAction() {
        $files = array();
        $em = $this->getDoctrine()->getManager();
        $doc = $em->getRepository('AdminDocumentBundle:Document')->findAll();
        foreach ($_POST as $p) {
            foreach ($doc as $d) {
                if ($d->getId() == $p) {
                    array_Push($files, "../web/".$d->getWebPath());
                }
            }
        }
        $Zip = new \ZipArchive();
        $zipName = 'Documents-'.time().".Zip";
        $Zip->open($zipName,  \ZipArchive::CREATE);
        foreach ($files as $f) {
            $Zip->addFromString(basename($f),  file_get_contents($f)); 
        }

        $response = new Response();
    $response->setContent(readfile("../web/".$zipName));
    $response->headers->set('Content-Type', 'application/Zip');
    $response->header('Content-disposition: attachment; filename=../web/"'.$zipName.'"');
    $response->header('Content-Length: ' . filesize("../web/" . $zipName));
    $response->readfile("../web/" . $zipName);
    return $response;
    }

行ヘッダーまですべて問題ありません。そして、ここに行くたびに、「警告:readfile(../ web/Documents-1385648213.Zip):ストリームを開くことができませんでした:そのようなファイルまたはディレクトリはありません」というエラーが発生しました。

なにが問題ですか?

また、ファイルをアップロードするときに、このファイルにroot権限があり、作成したZipファイルでも同じことが起こるのはなぜですか。

14
BrunoRamalho

解決済み:

$Zip->close();
header('Content-Type', 'application/Zip');
header('Content-disposition: attachment; filename="' . $zipName . '"');
header('Content-Length: ' . filesize($zipName));
readfile($zipName);

どうやらファイルを閉じることが重要です;)

9
BrunoRamalho

SYMFONY 3-4の例:

use Symfony\Component\HttpFoundation\Response;

/**
* Create and download some Zip documents.
*
* @param array $documents
* @return Symfony\Component\HttpFoundation\Response
*/
public function zipDownloadDocumentsAction(array $documents)
{
    $files = [];
    $em = $this->getDoctrine()->getManager();

    foreach ($documents as $document) {
        array_Push($files, '../web/' . $document->getWebPath());
    }

    // Create new Zip Archive.
    $Zip = new \ZipArchive();

    // The name of the Zip documents.
    $zipName = 'Documents.Zip';

    $Zip->open($zipName,  \ZipArchive::CREATE);
    foreach ($files as $file) {
        $Zip->addFromString(basename($file),  file_get_contents($file));
    }
    $Zip->close();

    $response = new Response(file_get_contents($zipName));
    $response->headers->set('Content-Type', 'application/Zip');
    $response->headers->set('Content-Disposition', 'attachment;filename="' . $zipName . '"');
    $response->headers->set('Content-length', filesize($zipName));

    @unlink($zipName);

    return $response;
}
19
Vincent Moulene

Symfony 3.2 +ファイルヘルパー を使用してブラウザにファイルをダウンロードさせることができるので:

public function someAction()
{
    // create Zip file
    $Zip = ...;

    $this->file($Zip);    
}
2
Tomáš Votruba

私のために働きなさい。ここで、$ archive_file_name = 'your_path_to_file_from_root /filename.Zip'。

$Zip = new \ZipArchive();

if ($Zip->open($archive_file_name, \ZIPARCHIVE::CREATE | \ZIPARCHIVE::OVERWRITE) === TRUE) {
  foreach ($files_data as $file_data) {

    $fileUri = \Drupal::service('file_system')->realpath($file_data['file_url']);
    $filename = $file_data['folder'] . $file_data['filename'];
    $Zip->addFile($fileUri, $filename);
  }
  $Zip->close();
}


$response = new Response();

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

// Send headers before outputting anything.
$response->sendHeaders();
$response->setContent(readfile($archive_file_name));
return $response;
0