2

Symfony 経由で提供される ZIP ファイルがあります。コントローラーは次のようになります。

$headers = [
    'Content-Type' => 'application/zip',
    'Content-Disposition' => 'attachment; filename="archive.zip"'
];
return new Response(file_get_contents($pathToFile), 201, $headers);

そして、これはうまく機能します。ただし、BinaryFileResponse を使用しようとすると (ドキュメントで推奨されているように)、ZIP ファイルが破損します。

$response = new BinaryFileResponse($pathToFile);
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT);
$response->setStatusCode(Response::HTTP_CREATED);
return $response;

ファイルを修正しようとしたときに得られる出力zip -FF archive.zip --out fixed.zip

zip warning: End record (EOCDR) only 17 bytes - assume truncated

(このコマンドはアーカイブを正しく修正します)

それはバグですか、それとも何か間違ったことをしていますか?

私のセットアップ:

  • シンフォニー 2.8.11
  • PHP 7.0.8
  • Ubuntu 16.04
  • nginx 1.10.0

編集:

提案された変更を行いましたが、問題はまだ存在します:

$response = new BinaryFileResponse($pathToFile);
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'archive.zip');
$response->headers->set('Content-Type', 'application/zip');
clearstatcache(false, $pathToFile);
return $response;

EDIT2:

もう 1 つ興味深いことがわかりました。この ZIP ファイルを標準の Response (作業コード) で提供すると、開くことができるファイルが作成されますが、実行zip -Tすると次のようになります。

zipfile の先頭または内部に余分な 1 バイト

元のファイルをテストすると、次のようになります。

わかった

ファイルのサイズは 1MB 未満です。

4

2 に答える 2

4

解決:

生成された ZIP ファイルをテキスト エディターで開くと、先頭に余分な空の行が見つかりました...

ob_clean();そのため、Response オブジェクトを返す前に追加したところ、機能するようになりました。

ただし、この改行文字がどこから来たのかはわかりません...

于 2016-09-27T13:29:57.847 に答える
0

201 http ヘッダーを返していることがわかりましたので、同じリクエストでファイルが作成されたと思います。symfony のドキュメントによると:

この同じ要求でファイルを作成したばかりの場合、ファイルはコンテンツなしで送信される可能性があります。これは、ファイルのサイズに対してゼロを返すキャッシュされたファイル統計が原因である可能性があります。この問題を解決するには、バイナリ ファイルへのパスを指定して clearstatcache(false, $file) を呼び出します。

于 2016-09-27T08:54:12.363 に答える