質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

zip

ZIPとは、複数のファイルをひとつにまとめて圧縮したり、圧縮したファイルを展開することができるアーカイブフォーマットです。 1998年以降のWindowsOS各バージョンで、標準の圧縮フォルダとして採用されています。 MacOSでも、X v10.3以降に他の圧縮ソフトとまとめてZIP機能を採用しています。

Amazon S3

Amazon S3 (Simple Storage Service)とはアマゾン・ウェブ・サービスが提供するオンラインストレージサービスです。

Q&A

解決済

1回答

2706閲覧

【PHP】 S3から複数のファイルを選択し、Zip化してダウンロードする機能はどうやって実現できるのか

sawamu

総合スコア11

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

zip

ZIPとは、複数のファイルをひとつにまとめて圧縮したり、圧縮したファイルを展開することができるアーカイブフォーマットです。 1998年以降のWindowsOS各バージョンで、標準の圧縮フォルダとして採用されています。 MacOSでも、X v10.3以降に他の圧縮ソフトとまとめてZIP機能を採用しています。

Amazon S3

Amazon S3 (Simple Storage Service)とはアマゾン・ウェブ・サービスが提供するオンラインストレージサービスです。

0グッド

0クリップ

投稿2019/08/23 02:35

編集2019/08/23 07:57

実現したい機能

複数ファイルをZip化してダウンロードする機能を実装したいです。または、Zip化せずに複数ダウンロード機能を実装したいです。
やり方や参考になる記事をご存知でしたら教えていただけると助かります????‍♂️

試したこと

※全てCakePHPを使用して実装しています。

①foreach
すでに1つずつのファイルダウンロード機能が実装できているので、foreachで処理を回す。処理は1回目のダウンロード時に終わってしまいますのでこのやり方はできませんでした。

php

1 if ($this->request->is(['patch', 'post', 'put'])) { 2 $data = $this->request->data; 3 $result = $this->Common->download($data['dl']); 4 if ($result['error'] == true) { 5 $this->Flash->error($result['message']); 6 return $this->redirect([]); 7 } 8 } 9 10 public function download($file_pass = '') 11 { 12 $params = [ 13 'Bucket' => S3_BUCKET_NAME, 14 'Key' => $file_pass 15 ]; 16 $file_name = str_replace('user_upload/', '', $file_pass); 17 18 $s3 = new S3Client([ 19 'credentials' => [ 20 'key' => S3_ACCESS_KEY, 21 'secret' => S3_SECRET_KEY 22 ], 23 'region' => S3_BUCKET_REGION, 24 'version' => 'latest' 25 ]); 26 27 try { 28 $result = $s3->getObject($params); 29 $len = $result['ContentLength']; 30 header('Content-Type: application/force-download;'); 31 header('Content-Length: '.$len); 32 header('Content-Disposition: attachment; filename= '.$file_name); 33 echo $result['Body']; 34 return; 35 } catch(S3Exception $e) { 36 $return = [ 37 'error' => true, 38 'message' => 'ダウンロードに失敗しました。' 39 ]; 40 return $return; 41 } 42 }

②記事を参考に

php

1]header('Content-Type: application/octet-stream'); 2header('Content-disposition: attachment; filename="file.zip"'); 3 4require "./aws.phar"; 5use Aws\S3\S3Client; 6 7$bucket = 'myBucket'; 8 9$client = S3Client::factory(array( 10 'key' => getenv('AWS_ACCESS_KEY_ID'), 11 'secret' => getenv('AWS_SECRET_KEY') 12)); 13 14$result = $client->getObject(array( 15 'Bucket' => $bucket, 16 'Key' => 'test.txt', 17 'SaveAs' => '/tmp/test.txt' 18)); 19 20$Uri = $result['Body']->getUri(); 21 22$fp = popen('zip -r - '.$Uri, 'r'); 23 24$bufsize = 8192; 25$buff = ''; 26while( !feof($fp) ) { 27 $buff = fread($fp, $bufsize); 28 echo $buff; 29} 30pclose($fp);

参照した記事

③ライブラリ
このライブラリで実現できるか検証しましたが、返り値がバイナリデータで上手く動作しませんでした。

何か方法やアイディアある方は教えていただけると助かります????‍♂️

参考にした記事

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2019/08/23 04:41

>※全てCakePHPを使用して実装しています。 CakePHPのタグを追加しておいてください。 いずれにしても「一度のリクエストで複数ダウンロード」は無理なので(レスポンスヘッダの関係かなと)「ダウンロードしたいファイルをまとめての一つのzipにする」という話ですかね
sawamu

2019/08/23 05:14

ありがとうございます! >「ダウンロードしたいファイルをまとめての一つのzipにする」 はい、そういう意味です。 >CakePHPのタグを追加しておいてください。 タグの件、承知しました!
guest

回答1

0

ベストアンサー

複数ダウンロードさせるのであれば、フロント側でボタンを押したらJavaScriptでファイルごとにリクエストを発生させてダウンロードさせるといった手法になるかと思います。javascript 複数ダウンロード でググってみてください。

サーバー側でzip化してダウンロードさせるのであれば、S3からの取得はaws-sdkを使用するとして、zipの作成にはPHPのzip拡張に含まれる ZipArchive を使用したほうがいいでしょう。

PHP: ZipArchive - Manual https://www.php.net/manual/ja/class.ziparchive.php

ZipArchive::openで、ファイルを開いた後、addFromStringでS3からのファイルを追加していけばよいでしょう。その後ZipArchiveをcloseして、書き出したファイルを出力すればよいです。

CakePHPであれば、ダウンロードリクエスト用のメソッドが準備されていますのでそれを使用してください。

リクエストとレスポンスオブジェクト - 3.8 https://book.cakephp.org/3.0/ja/controllers/request-response.html#cake-response-file

投稿2019/08/23 08:05

編集2019/08/23 08:07
nojimage

総合スコア957

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sawamu

2019/08/23 08:40 編集

ご丁寧にリンクなども貼っていただきありがとうございます!ご提案していただいた方法でやってみます????
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問