概要
Laravelを使ってAWS S3の画像をブラウザからDLするときに、
少しでも通信量を減らそうと思いZip化して落とそうと考えました
その際に検討したことを記していきます
前提
Zipの作成にはZipArchiveというライブラリを使用していますが、
その利用方法についてはこちらを参考ください
実装
クライアントの作成
まずAWS S3へアクセスするためにクライアントの作成が必要です
作成に必要なデータとしては以下
・バージョン:version
→基本的にlatest(最新)
・リージョン:region
→日本を設定(config)
・認証情報:credentials
→key,secretを設定(config)
データを一部以下configに定義しているので、そちらを参照するようにしています
config/filesystems.php
// S3に接続するための情報
$s3Config = [
'version' => 'latest',
'region' => config('filesystems.disks.s3.region'),
];
// ローカル環境用: IAMロールを使えないので情報を追加する
if (config('app.env') === 'local') {
$s3Config['credentials'] = [
'secret' => config('filesystems.disks.s3.secret'),
'key' => config('filesystems.disks.s3.key'),
];
}
$s3Client = new S3Client($s3Config);
S3からデータを取得
S3から画像を取得してみます
画像を取得するコマンドを作成し、実行します
$commands = [];
foreach ($imgs as $img) {
$key = $imgDir . $img;
$commands[] = $s3Client->getCommand(
'GetObject',
[
'Bucket' => $bucket,
'Key' => $key,
]
);
}
// 作成したコマンドの配列を実行
$command_pool_batch = CommandPool::batch($s3Client, $commands);
zip内へ格納
$zipはZipArchiveで作成したものに追加しています
コマンドが無事成功すれば、$value['Body']
から画像を取得しzipにつめていきます
foreach ($command_pool_batch as $i => $value) {
// 取得できなかったらS3Exceptionが格納される
if (strpos(get_class($value), 'S3Exception') !== false) {
// エラーログ出力
continue;
}
header("Content-Type: {$value['ContentType']}");
// ファイル名を指定(指定しない場合S3内のフルパスが使われる)
$fileName = $imgs[$i];
$zip->addFromString($fileName, $value['Body']);
}