PHPでフォルダをZIPに圧縮してダウンロードする。その後、ブラウザから解凍エラーで開けない場合の対策。


PHPで、サーバのフォルダをZIPにまとめて、それをダウンロードしたいなーと思ったら、落とし穴が。

ZIPにするまでは簡単だったのだけど、そのファイルをブラウザから自動ダウンロードして、解凍したらエラーが発生。。。 まったくもう・・・(溜息)

 

解決??

しましたとも!!先人のお知恵のお陰で!!

 

「var/www/.../download/test」の中に入っているファイル一式をまとめて
 ↓
「var/www/.../download/test.zip」というzipファイルにする。

 

 

PHP

zip("var/www/.../download/test"); // 圧縮処理関数を呼び出す

// 圧縮処理関数
function zip($zip_folder_path) {
  // コマンドでZIPにする
  $command =  "cd ". $zip_folder_path .";".
      "zip -r ". $zip_folder_path .".zip .";
  // Linuxコマンドで実行
  exec($command);

  // chmod($zip_folder_path .".zip", 0755); // 必要に応じて、パーミッション変更

  $path = explode("/",$zip_folder_path);
  $zip_filename = end($path).".zip";

  // 圧縮ファイルをダウンロードする。
  mb_http_output( "pass" ); // ★これ重要! readfileより先に記述すること
  header("Pragma: public");
  header("Content-Type:application/octet-stream");
  header("Content-disposition: attachment; filename=".$zip_filename);
  header("Content-Length: ".filesize($zip_folder_path));
  ob_end_clean(); // ★これ重要! 出力バッファをクリア
  readfile($zip_folder_path.".zip");

   //ファイル削除
  unlink($zip_folder_path.".zip"); // 削除はお好みで。
  exit;
}

 

最初、公式が勧めている通りに記述したら、ブラウザでダウンロードした時にエラーが発生して、解凍できなかった。
(不思議なことに、FTPで手動でダウンロードしてくると、解凍できる。)

 

試行錯誤の末、こちらのサイトの通りに設定したら、無事ブラウザからダウンロードして直接解凍できるようになった!!
参考サイト:zipファイルダウンロードで、zipファイルが壊れてダウンロード出来ない

 

mb_http_output( "pass" );
ob_end_clean();」出力バッファをクリア

 

 

その後(2017/10/30追記)

 

なお、このやり方で当初は上手くいっていたものの、PHP7にアップグレードしたあたり(←たぶん)から動作しなくなりました。

新しいコードはこちら。
PHPでフォルダをZIPに圧縮してダウンロードする。その後、ブラウザから解凍エラーで開けない場合の対策。その2