web-dev-qa-db-ja.com

PHP)のZipストリーム

PHPスクリプトを使用して、その場でZipファイルを作成し、ブラウザにZipファイルをダウンロードさせます。問題は、接続されている出力ストリームにZipファイルを直接書き込むことができるかどうかです。最初にサーバーに実際のファイルとして保存してからファイルを送信するのではなく、ユーザーのブラウザに送信しますか?

前もって感謝します。

18
user371254

WebサーバーがLinuxを実行している場合は、一時ファイルを生成せずにストリーミングを実行できます。 win32では、Cygwinなどを使用する必要がある場合があります。

Zipファイル名として「-」を使用すると、stdoutに圧縮されます。そこから、popen()を使用してそのストリームをリダイレクトするのは簡単です。 「-q」引数は、通常のステータステキストを出力しないようにZipに指示するだけです。詳細については、Zip(1)のマンページを参照してください。

<?
     $zipfilename = "Zip_file_name.Zip";

     if( isset( $files ) ) unset( $files );

     $target = "/some/directory/of/files/you/want/to/Zip";

     $d = dir( $target );

     while( false !== ( $entry = $d->read() ) )
     {
       if( substr( $entry, 0, 1 ) != "." && !is_dir( $entry ) ) 
       {
         $files[] = $entry;
       }
     }

     header( "Content-Type: application/x-Zip" );
     header( "Content-Disposition: attachment; filename=\"$zipfilename\"" );

     $filespec = "";

     foreach( $files as $entry )
     {
       $filespec .= "\"$entry\" ";
     }

     chdir( $target );

     $stream = popen( "/usr/bin/Zip -q - $filespec", "r" );

     if( $stream )
     {
       fpassthru( $stream );
       fclose( $stream );
     }
?>
13
weasel5i2

このライブラリはあなたが探しているもののようです: https://github.com/maennchen/ZipStream-PHP

10
Andreas Gohr

Zip拡張子 を使用している場合、答えは「いいえ」のようです。 ZipArchiveクラスのcloseメソッド が書き込みをトリガーするものであり、ファイルに書き込みたいようです。あなたmightは、 Streams を使用してファイルをシミュレートすることができますが、すべてをメモリに保持し、ファイルの追加が完了するまで、送信できませんでした。

Zipファイルが作成されるのをユーザーに待たせているときにタイムアウトやその他の問題が発生した場合は、複数のステップからなるダウンロードプロセスを試してください。

  1. ユーザーは、Zipを作成するために選択したものをすべて選択します
  2. それらは、ajax呼び出しを使用して実際にバックグラウンドでZipファイルを作成するステータスページに移動します。かわいくて気が散るアニメーションは彼らの注意を保つべきです。
  3. バックグラウンドプロセスがZipをビルドした後、ユーザーはダウンロードを実行するスクリプトにリダイレクトされます/ファイルにリダイレクトされます。
5
Charles

はい、次のgit repを使用してZipをクライアントに直接ストリーミングできます: Zip Stream Large Files

1
Artur Grigio