PHPでZIPファイルが開けない原因と解決方法

このQ&Aのポイント
  • PHPでZIPファイルが開けない原因とは?ファイルを出力する際に無効と表示されるときの解決方法を紹介します。
  • PHPでZIPファイルを出力する際にフォルダが開けない問題が発生する場合、その原因と解決方法は?詳しく解説します。
  • PHPでZIPファイルをheaderで出力すると無効と表示されてしまう問題について、その原因と解決策をご紹介します。
回答を見る
  • ベストアンサー

PHP Zip 開かない

よろしくお願いします。現在ZIPにしたものをheaderで出力したいのですが、 その場で解凍した際にフォルダを開くことができません無効ですと表示されます。 原因がわからず困っています。ヒントでも頂ければ助かります。 if(isset($_POST["upload"])){ $dir = file_zone; // Zipファイルの保存先 $file = "./Zipfile/" . date("his") .'.zip'; $root = ""; zipDirectory($dir, $file,$root); } function zipDirectory($dir, $file, $root){ $zip = new ZipArchive(); $res = $zip->open($file, ZipArchive::CREATE); if($res){ // $rootが指定されていればその名前のフォルダにファイルをまとめる if($root != "") { $zip->addEmptyDir($root); $root .= DIRECTORY_SEPARATOR; } $baseLen = mb_strlen($dir); $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $dir, FilesystemIterator::SKIP_DOTS |FilesystemIterator::KEY_AS_PATHNAME |FilesystemIterator::CURRENT_AS_FILEINFO ), RecursiveIteratorIterator::SELF_FIRST ); $list = array(); foreach($iterator as $pathname => $info){ $localpath = $root . mb_substr($pathname, $baseLen); if( $info->isFile() ){ $zip->addFile($pathname, $localpath); } else { $res = $zip->addEmptyDir($localpath); } } $zip->close(); } else { return false; } header('Content-Type: application/octet-stream'); header(sprintf('Content-Disposition: attachment; filename="%s"',basename($file))); header(sprintf('Content-Length: %d', filesize($file)) ); readfile($file); }

  • PHP
  • 回答数2
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

このコードの情報だけだと、どこでデータの異常がおきているのか、分からないですが、 サーバー上に生成されたzipファイルと、ダウンロードしたzipファイルの ファイルサイズや内容や日付を見比べてみれば、解決のヒントになるかもしれません。 たとえば、PHPで マルチバイトコードの自動変換を宣言してる場合は readfile() の結果のバイナリを PHPが勝手に自動変換して壊してしまうことがあります。 この場合は readfile($file);の前に mb_http_output( "pass" ) ; を入れると解決します。 (これは一例ではありますが、バイナリデータを送り出すするときに、結構はまってしまうこと多いです)

losloson
質問者

お礼

まさしくご指摘いただいた方法でうまくいきました!!! 本当、本当に、本当に、助かりました! ありがとうございます!

その他の回答 (1)

  • t_ohta
  • ベストアンサー率38% (5080/13276)
回答No.1

処理中に Notify レベルのエラーが発生すると、ダウンロードしたファイルにエラーメッセージが混入してファイルが壊れていると判断される事があります。 ダウンロードしたファイルをテキストエディタで開いてみて、エラーメッセージが混入していないか確認してみましょう。

losloson
質問者

補足

ありがとうございます。 Reading the archive file failed:Offset is out of bounds とでてきます CREATEしたZipが見つからないという意味合いでしょうか? 一度確認してみます。

関連するQ&A

  • Zip名 日付

    失礼します、現在指定したディレクトリにzipファイルを作成しているのですが、Zip名の頭に日付を付けたいです。 dateを使用しているのですが上手くいきませんストリームに出力する際のファイル名にdateはうまくいきましたが指定したディレクトリに保存した際のファイル名がうまくいきません。 自身でZipファイルの保存先にdateを使用してみましたがエラーが出てしまいます。 よろしくお願いします。 if(isset($_POST["upload"])){ $dir = file_zone; // Zipファイルの保存先 $file = './Zipfile/test.zip'; $root = ""; zipDirectory($dir, $file,$root); } function zipDirectory($dir, $file, $root){ $zip = new ZipArchive(); $res = $zip->open($file, ZipArchive::CREATE); if($res){ // $rootが指定されていればその名前のフォルダにファイルをまとめる if($root != "") { $zip->addEmptyDir($root); $root .= DIRECTORY_SEPARATOR; } $baseLen = mb_strlen($dir); $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $dir, FilesystemIterator::SKIP_DOTS |FilesystemIterator::KEY_AS_PATHNAME |FilesystemIterator::CURRENT_AS_FILEINFO ), RecursiveIteratorIterator::SELF_FIRST ); $list = array(); foreach($iterator as $pathname => $info){ $localpath = $root . mb_substr($pathname, $baseLen); if( $info->isFile() ){ $zip->addFile($pathname, $localpath); } else { $res = $zip->addEmptyDir($localpath); } } $zip->close(); } else { return false; } header('Content-Type: application/octet-stream'); header(sprintf('Content-Disposition: attachment; filename="%s"', date(ymdhis).basename($file))); header(sprintf('Content-Length: %d', filesize($file)) ); readfile($file); }

    • ベストアンサー
    • PHP
  • PHP 階層構造 維持 ディレクトリ

    現在指定したディレクトリを中にあるサブディレクトリやファイルを丸ごと階層構造を維持したまま圧縮したいのですが、うまくいきません下記のサイトを参考にしましたがエラーが出てしまいます。例外処理らしいのですが、ドキュメントを読んでもエラーの内容がうまく理解ができません よろしくお願いします。 http://php-archive.net/php/zip-directory/ エラー文 Fatal error: Uncaught Error: Call to undefined function zipDirectory() in C:\MAMP\htdocs\upload\upload-file.php:134 Stack trace: #0 {main} thrown in C:\MAMP\htdocs\upload\upload-file.php on line 134 コード define("file_zone","C:/MAMP/htdocs/upload/test/"); if(isset($_POST["download"])){ // 圧縮するディレクトリー $dir = dirname(__FILE__) . '/test/'; // Zipファイルの保存先 $file = dirname(__FILE__); zipDirectory($dir, $file); // ディレクトリを圧縮する function zipDirectory($dir, $file, $root=""){ $zip = new ZipArchive(); $res = $zip->open($file, ZipArchive::CREATE); if($res){ // $rootが指定されていればその名前のフォルダにファイルをまとめる if($root != "") { $zip->addEmptyDir($root); $root .= DIRECTORY_SEPARATOR; } $baseLen = mb_strlen($dir); $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $dir, FilesystemIterator::SKIP_DOTS |FilesystemIterator::KEY_AS_PATHNAME |FilesystemIterator::CURRENT_AS_FILEINFO ), RecursiveIteratorIterator::SELF_FIRST ); $list = array(); foreach($iterator as $pathname => $info){ $localpath = $root . mb_substr($pathname, $baseLen); if( $info->isFile() ){ $zip->addFile($pathname, $localpath); } else { $res = $zip->addEmptyDir($localpath); } } $zip->close(); } else { return false; } } }

    • ベストアンサー
    • PHP
  • PHP ZIP 展開できない

    PHPで作成したZipファイルが展開できません ダブルクリックで展開すると無効ですと表示されます。 よろしくお願いします。 define("file_zone","C:/MAMP/htdocs/upload/test/"); if(isset($_POST["download"])){ $path = file_zone; $files = scandir($path); $zip = new ZipArchive($files); // Zipファイル名 $zipFileName = "file_" . date("Ymds") .'.zip'; // Zipファイル一時保存ディレクトリ $zipTmpDir = file_zone; // Zipファイルオープン $result = $zip->open($zipTmpDir.$zipFileName, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE); if ($result !== true) { // 失敗した時の処理 } // 処理制限時間を外す set_time_limit(0); foreach ($files as $filepath) { $filename = basename($filepath); // 取得ファイルをZipに追加していく $zip->addFromString($filename,file_get_contents($filepath)); } $zip->close(); // ストリームに出力 header('Content-Type: application/zip; name="' . $zipFileName . '"'); header('Content-Disposition: attachment; filename="' . $zipFileName . '"'); header('Content-Length: '.filesize($zipTmpDir.$zipFileName)); echo file_get_contents($zipTmpDir.$zipFileName); // 一時ファイルを削除しておく // unlink($zipTmpDir.$zipFileName); }

    • ベストアンサー
    • PHP
  • PHP zipファイルのダウンロード

    下記のようなPHPスクリプトにおいて、zip フォルダに画像ファイルの圧縮ファイルを 保存し、ダウンロードしたいんです。ダウンロードの動作はChrome上で確認できてますが、圧縮した、ダウンロードファイルのサイズが0KB で、空なのです。 どこが間違っているか教えていただけますか? [file_zip.php] <?php mb_internal_encoding("UTF-8"); $ftp = ftp_connect("~"); ftp_login($ftp, "~", "~"); $dir = '/storage2/zip'; ftp_chdir($ftp, $dir); // ディレクトリ移動 // Zipクラスロード $zip = new ZipArchive(); // Zipファイル名 $zipFileName = $_POST['zip_filename']; var_dump($zipFileName); // Zipファイル一時保存ディレクトリ $zipTmpDir = '/storage2/zip'; // Zipファイルオープン $result = $zip->open($zipTmpDir.$zipFileName, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE); if ($result !== true) { // 失敗した時の処理 echo '圧縮ファイルをオープンできませんでした'; exit(); } // ここでDB等から画像イメージ配列を取ってくる $image_data_array = array(); array_unshift($image_data_array, $zipTmpDir.$zipFileName); // 処理制限時間を外す set_time_limit(0); foreach ($image_data_array as $filepath) { $filename = basename($filepath); // 取得ファイルをZipに追加していく $zip->addFromString($filename,file_get_contents($filepath)); } $zip->close(); // ストリームに出力 header('Content-Type: application/zip; name="' . $zipFileName . '"'); header('Content-Disposition: attachment; filename="' . $zipFileName . '"'); header('Content-Length: '.filesize($zipTmpDir.$zipFileName)); echo file_get_contents($zipTmpDir.$zipFileName); // 一時ファイルを削除しておく unlink($zipTmpDir.$zipFileName); // header("Location: storage.php"); ?>

    • 締切済み
    • PHP
  • PHPのZipArchiveでzipが作成できない

    PHPでzipファイルを作ろうと思い、以下の手順で作成しました。 $zip = new ZipArchive(); if($zip->open('./'.$zip_file, ZipArchive::CREATE | ZIPARCHIVE::OVERWRITE) === true){ while($row = $stmt->fetch()){ // いろいろと処理 $zip->addFile($file); } $zip->close(); } すると、ループ内で行っているaddFileは返り値すべてtrueなのに対して、最後のcloseでfalseが返ってきてしまいます。 ループ処理内では画像を追加しているのですが、結構数が多いので容量の問題とかあるのでしょうか。

    • ベストアンサー
    • PHP
  • PHP 再帰的 ZipArchive

    現在サブディレクトリの中のファイルも含めZipファイルを作成していのですがうまくいきません 説明がうまくできませんが下記のサブディレクトリのtestだけが表示されファイルが取得できません。できればpath_uploadの中を階層を変えずzipで圧縮して取得したいです。 なにとぞよろしくお願いします。 path_upload----test-----test.txt |--test2.txt |--test3.txt コード define("file_zone","C:/MAMP/htdocs/upload/path_upload"); if(isset($_POST["download"])){ $path = file_zone; $files = scandir($path); $zip = new ZipArchive($files); // Zipファイル名 $zipFileName = date("Ymd") .'.zip'; // Zipファイル一時保存ディレクトリ $zipTmpDir = file_zone; // Zipファイルオープン $result = $zip->open($zipTmpDir.$zipFileName, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE); if ($result !== true) { // 失敗した時の処理 } // 処理制限時間を外す set_time_limit(0); foreach ($files as $filepath) { $filename = basename($filepath); // 取得ファイルをZipに追加していく $zip->addFromString($filename,file_get_contents($filepath)); } $zip->close(); // ストリームに出力 if(ini_get('zlib.output_compression')) ini_set('zlib.output_compression', 'Off'); header('Content-Type: application/zip; name="' . $zipFileName . '"'); header('Content-Disposition: attachment; filename="' . $zipFileName . '"'); header('Content-Length: '.filesize($zipTmpDir.$zipFileName)); echo file_get_contents($zipTmpDir.$zipFileName); // 一時ファイルを削除しておく // unlink($zipTmpDir.$zipFileName); }

    • ベストアンサー
    • PHP
  • IEだと・・・だめなんです

    Zipファイルに固めてダウンロードさせようとしているのですが、Firefoxだとダウンロードできて、IEだとエラーが出てこけてしまいます。 まず、Header部分が原因だと思うのですが、原因分かる方いらっしゃいますか?教えてください。 header("Content-type: application/octet-stream"); header('Content-Disposition: attachment; filename="' . zip_file_name . '"'); header("Content-length: " . filesize($zip_file_name)); readfile($zip_file_name);

    • ベストアンサー
    • PHP
  • PHP:wavファイルのダウンロード

    音楽ファイルを会員に配信するサイトを運営しています。 mp3は問題なくダウンロード・再生できるのですが、wavファイルはダウンロードしてもファイルが破壊されており、再生できません。 wavファイルのバイト数に変化はありませんでした。FTPからファイルをダウンロードすると正常に再生できるので、問題はウェブでのダウンロードをする過程にあることは分かっています。いろいろ調べているのですがそれ以降の原因が分からず困っています。 誰か原因をご存知の方、目星の付く方などおられましたら、ぜひ解答お願いいたします。 ファイルダウンロードには、以下のようなphp関数を使っています。 function download_file($path_file){ if (!file_exists($path_file)) { die("Error: No Such File."); } if (($content_length = filesize($path_file)) == 0) { die("Error: File size is 0.(".$path_file.")"); } if($_POST['sort'] == mp3){ header("Content-Type: audio/mpeg"); }elseif($_POST['sort'] == wav){ header("Content-Type: audio/x-wav"); } header("Content-Disposition: attachment; filename=\"" .basename($path_file)."\""); header("Content-Length: ".$content_length); header("Content-Transfer-Encoding: binary"); $handle = fopen($path_file, 'rb'); while (!feof($handle)) { echo fread($handle, 4096); ob_flush(); flush(); } fclose($handle); }

    • 締切済み
    • PHP
  • PHPでバックアップ

    PHP初学者です、よろしくお願い致します。 PHPでバックアップを取りたく、次の様にしてみたのですが、実行するとファイルは正しいサイズでダウンロードされるのですが解凍すると中身は空になっています。できたファイルをFTPで別途ダウンロードして解凍してみると正常です。 $file = $storedir.$generatefile; $tstr = 'tar -C '.$upperdir. ' -czf '.$storedir.$generatefile.' '.$targetfolder; $result = system($tstr, $retval); if (file_exists($file)) { header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename='.basename($file)); header('Content-Transfer-Encoding: binary'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); header('Content-Length: ' . filesize($file)); ob_clean(); flush(); readfile($file); } ファイルが出来上がっていないのにダウンロードが始まってしまうからでしょうか?もしそうならファイルが出来上がってからダウンロードが始まるようにするにはどうしたら良いでしょうか? 根本的にやり方が良くないようでしたらそれもご指摘いただければありがたいです。よろしくお願いいたします。

    • 締切済み
    • PHP
  • phpプログラミングについて

    php初心者です。 ファイルをダウンロードして保存するプログラムを作成しています。 ダイアログを表示させる形式をとっているのですが、保存されたファイルが正しく開けないんです。 ワードの場合だとファイルが壊れ、テキストファイルの場合、htmlのコードが一緒に入ってしまいます。 以下にソースコードと、ファイルの表示結果も載せるので、アドバイスお願いします。 [download.php] <html> <head> <meta http-equiv = "Content-Type" content = "text/html; charset = UTF-8"> <title>testdownload</title> </head> <body> テキストリンクの場合<br> <a href = "sample.php">sampleファイルをダウンロードする</a> <br><br> フォームボタンの場合<br> <form method = "post" action = "sample.php"><input type = "submit" value = "download"></form> </body> </html> [sample.php] <html> <head> <meta http-equiv = "Content-Type" content = "text/html; charset = UTF-8"> <title>downloadphp</title> </head> <body> <?php $path_file = "./test2.txt"; $path_file = mb_convert_encoding($path_file,"Shift_JIS","AUTO"); /* ファイルの存在確認 */ if (!file_exists($path_file)) { die("Error: File(".$path_file.") does not exist"); } /* オープンできるか確認 */ if (!($fp = fopen($path_file, "r"))) { die("Error: Cannot open the file(".$path_file.")"); } fclose($fp); /* ファイルサイズの確認 */ if (($content_length = filesize($path_file)) == 0) { die("Error: File size is 0.(".$path_file.")"); } /* ダウンロード用のHTTPヘッダ送信 */ header("Content-Disposition: attachment; filename=\"".basename($path_file)."\""); header("Content-Length: ".$content_length); header("Content-Type: application/octet-stream"); /* ファイルを読んで出力 */ if (!readfile($path_file)) { die("Cannot read the file(".$path_file.")"); } ?> </body> </html> [test2.txt] これはテストです。 [ダウンロード後のtest2.txt] <html> <head> <meta http-equiv = "Content-Type" content = "text/html; charset = UTF-8"> <title>downloadphp</title> </head> <body> これはテストです。 </body> </html> 以上、よろしくお願いします。

    • 締切済み
    • PHP

専門家に質問してみよう