実現したいこと
ビューのリンククリックをトリガーに、S3バケット内に保存された複数のCSVファイルを取得し、
zipアーカイブ化してダウンロードしたいです。
実現できていること
- 特定のPrefixを指定して、該当するキーを持つオブジェクトを
app/tmp
にダウンロードする - ダウンロードしたファイルをzip圧縮する
という部分までは実現できています。
具体的には、app/Controller/Component/S3Component.php
にてCSVファイルのダウンロード、zip圧縮を行い、
app/controller/DownloadController.php
にてzipファイルをローカルにダウンロード、としたいのですが、
後者がうまくいかず、なぜか(おそらく該当のzipファイルが)ビュー上に文字化けした状態で表示されます。
各種バージョン情報
CakePHP : 2.10.20
PHP : 7.2.31
該当ソース群(抜粋)
app/Controller/Component/S3Component.php
php
1public function downloadCSVFiles($bucket, $file_path){ 2 // some settings 3 try{ 4 // download files from s3 bucket 5 $results = $client->listObjects([ 6 'Bucket' => $bucket, 7 'Prefix' => $file_path, 8 ]); 9 if (!empty($results)){ 10 $zip = new ZipArchive(); 11 if ($zip->open('tmp/test.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE) === TRUE) { 12 foreach($results['Contents'] as $result){ 13 $obj = $client->getObject([ 14 'Bucket' => $bucket, 15 'Key' => $result['Key'], 16 'SaveAs' => 'tmp/'.$result['Key'] 17 ]); 18 $zip->addFromString($result['Key'], file_get_contents('tmp/'.$result['Key'])); 19 } 20 $zip->close(); 21 } else { 22 debug('ERROR: zip open failed'); 23 } 24 }else{ 25 debug("ERROR: couldn't download csv files."); 26 } 27 } catch (S3Exception $e) { 28 debug('Error message: ' . $e->getMessage()); 29 } 30 return $zip; 31}
app/controller/DownloadController.php
php
1public function download($camp_id = null, $login_id = null, $file_name = null){ 2 $this->autoRender = false; 3 $bucket = Configure::read("csvExportBucketName"); 4 $zip = $this->S3->downloadCSVFiles($bucket, $camp_id.'/'.$login_id.'/'.$file_name); 5 6 if (!empty($zip)) { 7 header('Content-Disposition: attachment; filename='.$file_name.'.zip'); 8 9 $this->response->type('application/zip'); 10 $this->response->file('storage/'.$file_name.'.zip', ['download' => true]); 11 $this->response->download($file_name.'.zip'); 12 } 13}
以上となります。
おそらくController側のレスポンス作成部分がおかしいのだろうとは思っているのですが、イマイチ解決の糸口を掴めず、という状況です。
ご助力いただけると幸いです。
指摘・修正事項・不足しているソースなどあればお申しつけください。
ご回答お待ちしております。よろしくお願いします!
2020/07/27 追記★
事象としては変わらず「zipの中身が文字化けした状態でブラウザに表示されている」ままですが、
Controllerのソースを下記のように修正しました。また、debug()
でresponseを出力した際のキャプチャ(文字化けzip含む)を下記に添付します。
app/controller/DownloadController.php
修正版(1)
php
1public function download($camp_id = null, $login_id = null, $file_name = null){ 2 $this->autoRender = false; 3 $bucket = Configure::read("csvExportBucketName"); 4 $zip = $this->S3->downloadCSVFiles($bucket, $camp_id.'/'.$login_id.'/'.$file_name); 5 6 if (!empty($zip)) { 7 $file_path = WWW_ROOT.'storage'.DS.$file_name.'.zip'; 8 $this->response->type('application/zip'); 9 $this->response->type('content-Length: '.filesize($file_path)); 10 $this->response->type('Content-Disposition: attachment'); 11 $this->response->file($file_path, ['download' => true]); 12 debug($this->response); 13 } 14}
- ブラウザの状態
回答1件
あなたの回答
tips
プレビュー