8
11

More than 3 years have passed since last update.

PHP(Laravel)のZipArchiveを使って、S3にある画像をzipダウンロードする。

Posted at

実現したいこと

S3にある画像をまとめてダウンロードする。JavaScriptで無理やりやる方法もあるが、
ブラウザ側でアラートが発生するため、zipダウンロードを選択しました。

環境

  • macOS Mojave 10.14.6
  • Laravel6系
  • PHP7.2

流れ

  • S3を利用する設定をする。
  • S3->サーバーに画像をダウンロード
  • ZipArchiveを利用して画像をzipファイルにまとめる

- ダウンロードレスポンスとして、ブラウザに返す。

※当初、ZipArchiveよりも少し簡単に利用できそうな、
Zipperというパッケージの利用を考えていましたが、Laravel6系に対応していませんでした。

実装

※現時点では、自身のMacbook上でのみ動作を確認していおります。

S3を利用する設定をする。

envファイルに設定情報を記述します。

.env
AWS_ACCESS_KEY_ID=***
AWS_SECRET_ACCESS_KEY=***
AWS_DEFAULT_REGION=***
AWS_BUCKET=***

以下3つを一気に実装

  • S3->サーバーに画像をダウンロード
  • ZipArchiveを利用して画像をzipファイルにまとめる
  • ダウンロードレスポンスとして、ブラウザに返す。

一気に処理を書いていきます。適宜、メソッドや別クラスに処理を分けてください。

TestController.php

use ZipArchive;
use Aws\CommandPool;
use Aws\S3\S3Client;

(中略)

public function zipDownLoad(ZipArchive $zip)
{
    // バケット
    $bucket = config('filesystems.disks.s3.bucket');
    $imgDir = 'imgs';

    // 画像ファイル名
    $imgs = [
        'img1.jpg',
        'img2.jpg',
        'img3.jpg',
        'img4.jpg',
        'img5.jpg',
    ];

    // S3Client ※1
    $s3Client = new S3Client(
        [
            'version' => 'latest',
            'region' => config('filesystems.disks.s3.region');,
            'credentials' => [
                'secret' => config('filesystems.disks.s3.secret');,
                'key' => config('filesystems.disks.s3.key');,
            ],
        ]
    );

    // zipファイル名と保存先(あとで削除する)
    $zipFileName = 'test.zip';
    $zipFilePath = public_path() . '/' . $zipFileName;

    // レスポンスヘッダー
    $headers = ['Content-Type' => 'application/zip'];

    // 画像取得 ※2
    $commands = [];
    foreach ($imgs as $img) {
        $key = $imgDir . $img;
        $commands[] = $s3Client->getCommand(
            'GetObject',
            [
                'Bucket' => $bucket,
                'Key' => $key,
            ]
        );
    }

    $contents = CommandPool::batch($s3Client, $commands);

    // zipファイル作成 ※3
    $zip->open($zipFilePath, ZipArchive::CREATE | ZipArchive::OVERWRITE);

    foreach ($contents as $i => $content) {
        // 取得できなかったらS3Exceptionが格納されてる。
        if (strpos(get_class($content), 'S3Exception') !== false) {
            continue;
        }

        $zip->addFromString($imgs[$i], $content['Body']);
    }

    $zip->close();

    // おまじない ※4
    ob_end_clean();

    // 返却
    return response()
            ->download($zipFilePath, $zipFileName, $headers) // ※5
            ->deleteFileAfterSend(true); // ※6
}
  1. ※2のCommandPoolを使うため、Storageファサードではなく、S3Clientを生成しています。
  2. S3に対してまとめてコマンド実行しています。参考
  3. ZipArchive::CREATEは「新規作成」、ZipArchive::OVERWRITEは「存在していたら上書き」という意味
  4. この関数を実行しないとMacでは正しく解凍できない。参考
  5. 引数は(ファイルパス, ダウンロードされるサイトのファイル名, レスポンスヘッダー)。第2,3引数は任意
  6. レスポンス返却後にファイルを削除

参考サイト

8
11
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
11