Help us understand the problem. What is going on with this article?

Laravel S3で複数の画像をアップロードする

LaravelでAWS S3へ画像をアップロードする

前提条件

AWS S3でユーザ登録とバケットの作成ができていること。
まだ作成してない方はこちらが参考になります

S3パッケージインストール

パッケージはflysystem-aws-s3-v3を使用します。
以下を実行してインストールしてください。

composer require league/flysystem-aws-s3-v3

ファイルシステム設定

/config/filesystems.phpを以下のように編集します。

  'default' => env('FILESYSTEM_DRIVER', 'local'),

  // 追記
  'cloud' => env('FILESYSTEM_CLOUD', 's3'),

  // 〜 略 〜

  'disks' => [
    'local' => [
      // 〜 略 〜
    ],
    'public' => [
      // 〜 略 〜
    ],

    // 以下を追記
    's3' => [
      'driver' => 's3',
      'key' => env('AWS_ACCESS_KEY_ID'),
      'secret' => env('AWS_SECRET_ACCESS_KEY'),
      'region' => env('AWS_DEFAULT_REGION'),
      'bucket' => env('AWS_BUCKET'),
    ],

環境変数設定

プロジェクト直下にある.envファイルを以下のように編集します。

AWS_ACCESS_KEY_ID='AWSで作成したAccess key ID'
AWS_SECRET_ACCESS_KEY='AWSで作成したSecret access key'
AWS_DEFAULT_REGION=ap-northeast-1
AWS_BUCKET='作成したバケット名'

Laravelの実装

実際にS3に保存していきます。
最低限のコードは次節以降になります。

viewの実装

今回は複数枚アップロードできるようにしていきます。

          <div class="name-filed width">
            <div class="first-name-box">
              <div class="text-label">
                <p class="name">希望画像<span class="red">✳︎必須(5枚まで可)</span></p>
              </div>
              <div>
              {!! Form::file('item_url[]', ['multiple' => 'multiple']) !!}
              </div>
              @if ($errors->has('item_url') || $errors->has('item_url.*') )
                <div class="alert alert-danger">{{ $errors->first('item_url') . $errors->first('item_url.*') }}</div>
              @endif
            </div>
          </div>

point 1

formに'multiple' => 'multiple'をつけることで複数選択が可能になる。(Ctrl キーなどを押しながら写真を選択する)

point 2

Form::file()メソッドを利用します。
今回は複数枚になるので第一引数は配列で取得できるようにします。

'item_url[]'

余談

配列にフォームリクエストでバリデーションする場合は下記のように、 .* というプレースホルダーが使用する。

item_url.*

controllerの実装

formから送られてきた値をS3に保存していきます。
laravelには簡単にS3を扱えるようにするファイルストレージ機能があります。
簡単なのでぜひ目を通してくださいね!

public function store(ItemRequest $request)
    {
        $disk = Storage::disk('s3');
        $images = $request->file('item_url');
        foreach ( $images as $image) {
            $path = $disk->putFile('itemImages', $image, 'public');
            $url[] = $disk->url($path);
        }

        return view('item.top');
    }

流れの解説
$disk変数にlaravelが用意してくれている Storage::disk('s3');を代入。

$imageにはformから送られてきた写真をfile()を使用して取得する。                                
※$imageにはURLではなく、UploadedFile クラスが入ってる。

foreachを使用して画像一枚ずつS3に保存していく。
putfile()メソッドの第一引数はバケット内の保存するフォルダを指定している。第二引数は保存する値。第三引数でpublicにすることでどのユーザーでもweb上で画像を見ることが可能になる。※指定しないとweb上に画像が表示されない。
$pathの中身は"バケットの保存先のフォルダ/画像"のpathになっています。
ここまででS3への保存は完了になります!

最後の$urlにはurl()を使用してS3からのURLを作成しています。

以上でS3への複数枚画像アップロードは完了になります!

RentaSakai
あなたのお悩みを1分で解決いたします。(僕が詰まったところを載せてます)
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした