LoginSignup
8
7

More than 5 years have passed since last update.

【AWS SDK for PHP】1000以上のファイルがあるS3バケットの内容を取得する

Last updated at Posted at 2018-01-21

やりたいこと

PHPでS3バケットにあるファイルのリストを取得する際、AWS SDK for PHPのListObjectsメソッドListObjectsV2メソッドが使えます。v1とv2ではパラメーターの設定方法や返り値が若干異なるだけで中身は同じです。どっちでもいいのですが今回はv2でいきます。

しかし困ったことに一度に1,000件までしか取得できない...さすがにそれは不便すぎる

解決策

バケットにオブジェクトが1000より多く存在する時、ListObjectV2の返り値のIsTruncatedがtrueになることを利用します。
ちなみに'truncated'は切り捨てという意味で、取りこぼしたやついるよ〜っていう主張でしょうね。
さて、IsTruncatedがtrueの時、返り値のNextContinuationTokenに、今取得したリストの次から取得するためのトークンが入っています。これをリクエストパラメーターContinuationTokenに入れてあげてもう一回1000件取得...を繰り返していけばいいわけです。

結果的にコードは次のようになりました。

use Aws\S3\S3Client;

$config = [
    'credentials' => [
        'key' => '*** アクセスキー ***',
        'secret' => '*** シークレットキー ***',
    ],
    'region' => '*** リージョン ***',
    'version' => '2006-03-01'
];
$bucket = '*** バケット名 ***';
$prefix = '*** プレフィックス ***';


$client = S3Client::factory($config);

$object_list = GetObjectList($client, $bucket, $prefix);



function GetObjectList($client, $bucket, $prefix, $continuous_token=null)
{
    $result = $client->ListObjectsV2([
        'Bucket' => $bucket,
        'Prefix' => $prefix,
        'ContinuationToken' => $continuous_token
    ]);

    $object_list = [];
    if (isset($result['Contents'])) {
        foreach ($result['Contents'] as $object) {
            // 名前がxxxx/のオブジェクト(フォルダ)はリストに含めない
            if(substr($object['Key'], -1, 1) !== '/') {
                $object_list[] = 's3://'.$bucket.'/'.$object['Key'];
            }
        }

        if($result['IsTruncated'] === true) {
            $object_list = array_merge($object_list, GetObjectList($client, $bucket, $prefix, $result['NextContinuationToken']));
        }
    }

    return $object_list;
}
8
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7