LaravelでS3にある画像を全てローカルにコピーする

私が個人開発しているWebサービスでは、本番環境でAWS S3を使用し、ユーザーのプロフィール画像などを保存しています。しかし開発環境ではAWSの利用削減のために、なるべくローカルに画像などを保存してアクセスしたいはずです。

今回はS3のファイルを全てローカルにコピーする方法をご紹介します。

S3にあるファイルを全てローカルにコピーする(実コード)

私の場合はArtisanコマンドを作成し、「php artisan dev:images」などを実行してコピー出来るようにしています。
その際のhandle関数はこちら。

App\Console\Commands\CopyS3FilesToStorage.php
/**
 * 保存するS3バケットのディレクトリ
 *
 * @var array
 */
protected $shouldCopyDirectories = [
    'user-profile-images',
    'team-profile-images',
];

public function handle()
{
    $prodS3Disk = Storage::disk('s3');

    // ディレクトリにある全てのファイルを一次元配列として取得
    // ディレクトリの中にディレクトリがあっても再帰的に取得されます
    $allFiles = array_reduce($this->shouldCopyDirectories, function ($stack, $directory) use ($prodS3Disk) {
        array_push($stack, ...$prodS3Disk->allFiles($directory));
        return $stack;
    }, []);

    // ファイル数を取得しプログレスを開始
    $bar = $this->output->createProgressBar(count($allFiles));

    $publicDisk = Storage::disk('public');

    // コピー処理
    foreach ($allFiles as $file) {
        // 既にコピーされていればコピーを実行しません
        if (!$publicDisk->exists($file)) {
            $publicDisk->put($file, $prodS3Disk->get($file));
        }

        // プログレスを進める
        $bar->advance();
    }

    // プログレスを終了
    $bar->finish();
}
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.