- 締切済み
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"); ?>
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- mpro-gram
- ベストアンサー率74% (170/228)
補足をみても、どっちにどんなデータがあるのかよけい解らなくなった。 相変わらず、header送信前に、文字列出力してるから、ダウンロード画面にはならないだろうけど、それ以前にzipファイル自体が作れてない模様。 まずは、処理の段階を追って小分けプログラムでどこまでできてるのかチェックするのが先かな? 1.detail.php からの送信データ受け取りチェック 2.zipファイル作成:前回の私の認識が間違ってた気がするけど、zip に入れる元ファイルが ftp 接続先にあるのですか? ディレクトリー位置とか、ftp 先と自前内部と区別できてないように見受ける。 3.ファイルダウンロード あと、エラーは出てないのでしょうか?
- mpro-gram
- ベストアンサー率74% (170/228)
途中でvar_dumpしてるけど、このままだと、header出力が無効になってしまうけど、そこは、ちゃんとコメントアウトしたうえでという話かな? で本題、ftp接続先にzipファイルを作成後、それをもらって出力しているつもりのようですが、$zipTmpDir.$zipFileName だけの指定では、自前サーバー内部を指定したことになり、そこにはファイルがないので、エラーか0しか返さないのだと思われます。 ftp_get($ftp, 'localfile_name', $zipTmpDir.$zipFileName, FTP_BINARY ) で、自前サーバー側に一度取得しておく必要があるでしょう。 あと、セキュリティ上気になったのは、ファイル名に $_POST['zip_filename'] の値をそのまま使ってると、どんなとんでもない値をいれてくるか解らないので、半角英数字のみなのかなどをチェックした方がよいですよ。
お礼
詳しいご回答、どうも有難うございました。
補足
下記のように、detail.phpから、zipfile.phpに、「ここ」ボタンをクリックすることで リダイレクトするはずなのですが、ページが、zipfile.phpに遷移しません。 どこが間違っているのでしょうか。そのせいで、ダウンしたファイルサイズが0KBなのでしょうか? 「detail.php側」 <!DOCYTPE html> <html> <head><title>画像ファイル詳細画面</title></head> <body> <table width="1000" rows="1" cols="30" border="1" bordercolor="#FFFFFF" bgcolor="lightgreen"> ~ 中略 ~ <?php $user = $_SERVER['REDIRECT_REMOTE_USER']; // .htaccessで認証されたユーザー名 $filename = $_GET['filename']; $type = $_GET['type']; $dir = './'.$user.'/'; $filename2=$dir.$filename; if($type==="画像属性詳細" || $type==="文書"){ $fp = fopen($filename2, 'r'); $buf = fgets($fp); $title = strtok($buf, ','); $date = strtok(','); $sender = strtok(','); $syurui = strtok(','); // $filename = strtok(','); strtok(','); // ファイル名読み飛ばし $size = strtok(','); $size=round(filesize($filename2)/1024, 2); // $type = strtok(','); $type = mime_content_type($filename2); strtok(','); // mimeの分を読み飛ばし $setsumei = strtok(','); fclose($fp); }elseif($type==="画像ファイル本体"){ $filename4 = $filename; $base = substr($filename, 0, strlen($filename)-4); $filename3 = $dir.$base.".txt"; $fp = fopen($filename2, 'rb'); // バイナリモード $img = fread($fp, 50000000); // 最大5MBまで読み込む fclose($fp); $fp = fopen($filename3, 'r'); $buf = fgets($fp); $title = strtok($buf, ','); $date = strtok(','); $sender = strtok(','); $syurui = strtok(','); // $syurui = "画像ファイル本体"; $size= round(filesize($dir.$filename4)/1024, 2); $type = mime_content_type($dir.$filename4); // 引数はパス(ファイル名ではない) strtok(','); // ファイル名の分を読み飛ばし strtok(','); // ファイルサイズの分を読み飛ばし strtok(','); // mimeタイプの分を読み飛ばし $setsumei = strtok(','); fclose($fp); } ?> <tr><td>タイトル</td><td><?php echo $title;?></td></tr> <tr><td>登録日時</td><td><?php echo $date;?></td></tr> <tr><td>登録者</td><td><?php echo $sender;?></td></tr> <tr><td>種別</td><td><?php echo $syurui;?></td></tr> <tr><td>ファイル名</td><td><?php echo $filename;?></td></tr> <tr><td>サイズ</td><td><?php echo $size;?>KB</td></tr> <tr><td>タイプ</td><td><?php echo $type;?></td></tr> <tr><td>説明</td><td><?php echo $setsumei;?></td></tr> <?php //echo '<tr><td>ダウンロード</td><td><a href="zipfile.php?zip_filename='.$filename4.'">ここ</a>をクリックしてください</td></tr>'; echo '<form name="form1" method="POST" action="zipfile.php">'; echo '<input type="hidden" name="filename" value="'.$filename4.'">'; echo '<tr><td>ダウンロード</td><td><input type="submit" value="ここ">をクリックしてください</td></tr>'; echo '</form>'; ?> </table> </body> </html> ------------------------------------------------------------------------------------- 「zipfile.php側」 <?php echo 'in zip'; $user = $_SERVER['REDIRECT_REMOTE_USER']; // .htaccessで認証されたユーザー名 mb_internal_encoding("UTF-8"); $ftp = ftp_connect("~"); ftp_login($ftp, "~", "~"); $dir = '/storage2/'.$user; ftp_chdir($ftp, $dir); // ディレクトリ移動 // Zipクラスロード $zip = new ZipArchive(); // Zipファイル名 $zipFileName = $_POST['filename']; //var_dump($zipFileName); // Zipファイル一時保存ディレクトリ $zipTmpDir = '/storage2/zip'; $zip->addFile($zipTmpDir.$zipFileName); // ZIPアーカイブにファイルを追加 // Zipファイルオープン $result = $zip->open($zipTmpDir.$zipFileName, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE); if ($result !== true) { // 失敗した時の処理 echo '圧縮ファイルをオープンできませんでした'; exit(); } // ここでDB等から画像イメージ配列を取ってくる ftp_get($ftp, $zipFileName, $zipTmpDir.$zipFileName, FTP_BINARY ); // 自前サーバーに取得 $image_data_array = array(); array_unshift($image_data_array, $zipTmpDir.$zipFileName); ftp_close($ftp); // 処理制限時間を外す 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); ?>