###実現したいこと
PHPでリンクをクリックすると自動でダウンロードが始まる機能を実装しました。
ローカル環境では動作しますが、グローバルサーバにアップロードするとダウンロードリンクがうまく機能せず、ページが遷移してしまいます。
プログラムの改善点やアドバイスをいただければ幸いです。
###追記
Ziparchiveを導入したところページは動作しましたが、できていたZIPファイルの出力ができなくなってしまいました。
・ディレクトリ
download.php
csv(フォルダ)
image(フォルダ)
の位置関係です。
###環境
さくらVPS ubuntu
PHP
1<?php 2namespace My; 3 4/** 5 * ZipArchiveを拡張して、ディレクトリまるまる扱う機能を追加 6 */ 7class MyZipArchive extends \ZipArchive 8{ 9 /** 10 * ディレクトリをまるごとzipファイルにします。 11 * 12 * @param string $dir ディレクトリパス 13 * @param string $inner_path zipファイル中のディレクトリパス 14 * @param bool $create_empty_dir 空ディレクトリもディレクトリを作成するか 15 * @return bool 処理の成否 16 */ 17 public function addDir($dir, $inner_path, $create_empty_dir=false){ 18 $items = \array_diff(\scandir($dir), ['.','..']); 19 $item_count = \count($items); 20 21 if($create_empty_dir || $item_count > 0){ 22 $this->addEmptyDir($inner_path); 23 } 24 25 // 追加するものがないならここで終了する 26 if($item_count === 0) return true; 27 28 29 foreach($items as $_item){ // forで行うなら$itemsは一旦array_values()を通したほうがいい 30 $_path = $dir . DIRECTORY_SEPARATOR . $_item; 31 $_item_inner_path = $inner_path . DIRECTORY_SEPARATOR . $_item; 32 33 // ディレクトリの場合は再帰的に処理する 34 if(\is_dir($_path)){ 35 $_r = \call_user_func( // "$this->addDir"より保守的に好ましい 36 [$this, __FUNCTION__], $_path, $_item_inner_path); 37 if(!$_r) return false; 38 } 39 // ファイルの場合でかつ処理に失敗したときはこちら 40 else if(!$this->addFile($_path, $_item_inner_path) 41 && !$this->on_recursive_error($dir, $inner_path, $create_empty_dir)){ 42 return false; 43 } 44 // ファイルの追加成功時は何も他には行わない 45 } 46 47 return true; 48 } 49 50 /** 51 * 再帰的処理のときにエラーが生じたらどうするかを定義しています。 52 * 53 * @param string $parent_dir ディレクトリパス 54 * @param string $parent_inner_path zipファイル中のディレクトリパス 55 * @param bool $create_empty_dir 空ディレクトリもディレクトリを作成するか 56 * @return bool Falseならその場で中断 57 */ 58 private function on_recursive_error($parent_dir, $parent_inner_path, $create_empty_dir){ 59 // 自由に定義してください 60 return false; 61 } 62} 63 64 65/* 66 * 下記は、質問本文のコードをちょっと改造してのテスト 67 */ 68 69//Zipクラスロード 70$zip = new MyZipArchive(); 71 72//Zipファイル名指定 73$zipFileName = '***.zip'; 74 75//Zipファイル一時保存ディレクトリ取得 76$zipTmpDir = '../'; 77 78// Zipファイルのパス 79$zip_file = $zipTmpDir . DIRECTORY_SEPARATOR . $zipFileName; 80 81//Zipファイルオープン 82$result = $zip->open($zip_file, \ZIPARCHIVE::CREATE | \ZIPARCHIVE::OVERWRITE); 83 84if ($result !== true) { 85 return false; 86} 87 88//処理制限時間を外す 89set_time_limit(0); 90 91// ※今回の肝 92$zip->addDir('csv', 'csv', true); 93$zip->addDir('images', 'images', true); 94 95$zip->close(); 96 97 98// ストリームに出力 99header('Content-Type: application/zip; name="' . $zipFileName . '"'); 100header('Content-Disposition: attachment; filename="' . $zipFileName . '"'); 101header('Content-Length: '.filesize($zip_file)); 102echo file_get_contents($zip_file); 103 104// 一時ファイルを削除しておく 105unlink($zip_file); 106exit(); 107?> 108
参考
https://ja.stackoverflow.com/questions/14416/複数ファイルや-フォルダも含むディレクトリをまるごとzipで圧縮して-ダウンロードさせたい
回答1件
あなたの回答
tips
プレビュー