概要
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']);
        }
