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

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

新規登録して質問してみよう
ただいま回答率
85.49%
PHP

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

リサイズ

コントロール、ウィンドウ、フォームやスクリーンのサイズ変更を指します。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

Q&A

解決済

1回答

7091閲覧

【AWS】PHPでS3に格納されている画像を取得する

sw34PildK

総合スコア7

PHP

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

リサイズ

コントロール、ウィンドウ、フォームやスクリーンのサイズ変更を指します。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

0グッド

0クリップ

投稿2017/05/17 12:11

AWS S3のPHPからの操作に関しての質問です。

S3バケットに画像が10万枚ほどありまして、この画像のURLを一括で取得したいと思い、他のWEBサイトを参照しつつ以下のようなコード書きました。

PHP

1require_once('aws.phar'); 2use Aws\S3\S3Client; 3use Aws\S3\Exception\S3Exception; 4 5date_default_timezone_set('Asia/Tokyo'); 6 7$key = '{key}'; 8$secret = '{secret}'; 9$region = 'us-east-1'; 10 11$S3 = S3Client::factory([ 12'credentials' => [ 13 'key' => $key, 14 'secret' => $secret 15], 16'region' => $region, 17'version' => '2006-03-01' 18]); 19 20ListAllObjects($S3, "{bucket_name}", $marker = null, $delimiter=null); 21 22function ListAllObjects($S3, $bucket, $marker = null, $delimiter=null){ 23 $objects = $S3->ListObjects(array( 24 'Bucket' => $bucket, 25 'Marker' => $marker, 26 'Delimiter' => $delimiter 27 )); 28 29 if(isset($objects["Contents"])){ 30 foreach ((array)$objects["Contents"] as $object) { 31 if(substr($object['Key'],-1,1) != "/"){ 32 unset($latest); 33 $latest = "s3://{$bucket}/{$object['Key']}"; 34 file_put_contents("export.csv", $latest . ",\n", FILE_APPEND); 35 } 36 } 37 if($objects["IsTruncated"] === TRUE){ 38 $key = ltrim($latest,"s3://{$bucket}/"); 39 ListAllObjects($S3, $bucket, $key, $delimiter); 40 } 41 } 42}

ここではわかりやすいように結果をcsvに落としています。

これを実行すると画像の取得量が多すぎるのかmemory exhaustedのエラーが出ます。

結果吐き出されたexport.csvを見るとどれについても同じURLが50回程度表示されていました。同じURLを取得することがなければmemory exaustedすることはないだろうと予想しているのですが、コードを見返してもなぜ同じ結果が複数回出力されるのかがわかりません。

これと違う方法でも構わないのですが、なんとかバケットに入っている画像すべてを取得したいです。何か解決方法がありましたらご教示いただきたいです。

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

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

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

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

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

guest

回答1

0

ベストアンサー

S3はその名の通り、拠点の異なるデータセンターに存在するストレージデバイスで管理されています。
ファイルを1つの拠点にUPLOADすると他の2拠点に対して同期するようになっています。

S3は、多くのストレージデバイスと異なり、S3バケットS3オブジェクトというものしかありません。
ファイルとフォルダは同じS3オブジェクトと認識されており、
S3バケット直下にすべてのオブジェクトが存在しています。
#システムが、URLの最後に"/"があったらフォルダというオブジェクトとみなすとしています。

bucket1 [bucket] ├ dir1/ [dir] | └ dir2/ [dir] | └ file1 [File] └ file2 [file]

の場合は

bucket1 [bucket] ├ dir1/ [obj] ├ dir1/dir2/ [obj] ├ dir1/dir2/file1 [obj] └ file2 [obj]

のようになっています。

S3に対してLISTリクエストを発した場合は、内部的にLISTリクエストのjsonが発行されます。

オブジェクトを読み込み、これはファイルで、これはフォルダーという風に1個ずつ読み込んで
かつ、他のストレージにファイルがあるのか無いのかを確認して、
バッファに溜め込みリフレッシュされます。そのために、時間がかかります。

再度リクエストすると同じjsonクエリを発行しているため、
また頭から同じように読み込んでいきますのでキャッシュ化されていないため
同じ時間がかかりますし、同じ結果が返ってきます。

10万オブジェクトのリストを作成するのであれば、
フィルターを掛けて検索させないと無理かと思います。
単純にファイルリストを取得したいだけであれば AWS CLI を利用する方法もあります。
WEBで動かさない分、通信とか気にしなくて良いので良いかと思いますよ。
s3api list-objects-v2

追記

AWSCLIは単純なCUIのコマンドです。

** 1.EC2インスタンスにて以下をインストール **
yum install aws-cli
yum install jq

** 2.AWSの設定ファイルを作成する **
aws configure

text

1AWS Access Key ID []: AAAAAAAAAAAAAAAAAAAA ←自分のアクセスキーを入力する 2AWS Secret Access Key []: AAAAAAAAAAAAAAAAAAAA ←自分のシークレットアクセスキーを入力する 3Default region name []: ap-northeast-1 ←自分の使っているリージョンを入力する 4Default output format []: json ←入力する

** 3.接続確認 **
aws s3 ls

** 4.取得コマンドを実行する **

aws s3api list-objects-v2 --bucket [バケット名] | jq '.Contents[].Key' | sed s/\"//g 1> /tmp/s3list.txt 2> /tmp/s3list_err.txt

途中から始めたいならば

aws s3api list-objects-v2 --bucket [バケット名] --start-after [LISTのここから表示を始めるオブジェクト名] | jq '.Contents[].Key' | sed s/\"//g 1> /tmp/s3list.txt 2> /tmp/s3list_err.txt

投稿2017/05/18 08:38

編集2017/05/25 03:04
lazhuward

総合スコア1294

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

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

sw34PildK

2017/05/24 04:59

ご回答ありがとうございます!レスポンスが遅くなってしまい大変申し訳ありません。 そうなのですね...CLIでやるしかなさそうですね... 貼ってくださったリンク先でCLIをみたのですが、いまいちどのように使っていいのかわかりません。もしよろしければサンプルコードなど書いていただければと思うのですが、可能でしょうか?
lazhuward

2017/05/25 03:02

追記しました。 単純なCUIのコマンドです。
sw34PildK

2017/05/26 07:48

ありがとうございます!おかげさまで無事に取得できました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問