やりたいこと
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;
}