4

次のコードを使用して、ディレクトリからzipファイルを作成し、httpダウンロードを介してユーザーに提供しようとしています:

 // write the file
file_put_contents($path . "/index.html", $output);

// zip up the contents
chdir($path);
exec("zip -r {$course->name} ./");

$filename = "{$course->name}.zip";

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' .urlencode($filename));
header('Content-Transfer-Encoding: binary');

readfile($filename);

zip ファイルを作成することはできますが、http 経由でダウンロードすることはできません。ftp クライアントを使用して作成された zip ファイルをダウンロードすると、Mac の Stuffit Expander はファイルを正常に解凍しますが、http 経由でダウンロードすると、Mac の解凍ツールが無限ループを作成します。これが意味することは、ダウンロードしたファイルが course.zip と呼ばれ、ファイルを解凍すると course.zip.cpgz が得られ、そのファイルを解凍すると course.zip が再び得られるということです。

誰にもアイデアはありますか?

ありがとう!

4

4 に答える 4

8

この問題があり、ダウンロードした zip ファイルの最初に新しい行が挿入されていることがわかりました。

ob_clean と flush 関数を使用して解決

    header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: private",false);
    header("Content-Type: application/octet-stream");
    header("Content-Disposition: attachment; filename=".basename($archive_file_name));
    header("Content-Transfer-Encoding: binary");
    header("Content-Length: ".filesize($archive_file_name));
    ob_clean();
    flush();
    echo readfile("$archive_file_name");
于 2009-11-23T16:06:07.007 に答える
1

karim79が提案したように、私のコメントを答えとして入れておきます: MIME タイプを application/octet-stream から application/zip に変更するとどうなりますか?

また、コマンド ライン zip プログラムを使用しているようですが、zip の成功をチェックしておらず、エンド ユーザーのブラウザに送信する前にファイルが存在するかどうかもチェックしていません。手動で zip を使用してファイル名をハードコーディングして、適切な形式の zip ファイルであることを確認してから、コードがそれをブラウザーに適切に出力するかどうかを確認してください。

于 2009-09-17T01:20:07.883 に答える
1
  1. 要求されるたびに再圧縮するのは得策ではありません。ZIP ファイルがまだ存在しない場合にのみ実行してみてください。

  2. が揮発性ファイルまたは圧縮して転送したい単一の小さなファイルである場合は、ob_start('ob_gzhandler')代わりに、より単純で、より小さく、よりクリーンなファイルを使用してみてください。ファイルは圧縮されて転送されますが、クライアント側によって元の形式で保存されます。

  3. Content-Length ヘッダーの指定は、ダウンローダがファイルの終わりを認識できるようにするために必要です。これにより、進行状況の制御、ファイルの破損の検出、および HTTP セッションのハングの回避 (接続が Keep-Alive モードの場合) が可能になります。このヘッダーがないことが問題の根本です。

于 2009-09-17T01:23:03.537 に答える
0

表示されているのは、アーカイブ ユーティリティが zip ファイルを zip ファイルとして認識せず、zip アーカイブ自体を圧縮しようとしたことです。2 番目の操作は、作成された最初のファイルを単純に解凍するため、実際にファイルを開くことはありません。これは、zip が破損していることが原因です。

ダウンロード プロセス中に、ブラウザが何らかの方法で zip ファイルを破損した可能性があります (改行変換はありますか?)。前述のように、MIME タイプを確認し、php header() を使用して正しい MIME タイプ (application/zip) を設定します。

于 2009-09-17T01:22:19.393 に答える