いくつかのファイルをアップロードするアプリケーションが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ファイルでも同じことが起こるのはなぜですか。
解決済み:
$Zip->close();
header('Content-Type', 'application/Zip');
header('Content-disposition: attachment; filename="' . $zipName . '"');
header('Content-Length: ' . filesize($zipName));
readfile($zipName);
どうやらファイルを閉じることが重要です;)
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;
}
Symfony 3.2 +は ファイルヘルパー を使用してブラウザにファイルをダウンロードさせることができるので:
public function someAction()
{
// create Zip file
$Zip = ...;
$this->file($Zip);
}
私のために働きなさい。ここで、$ 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;