LoginSignup
107
124

More than 5 years have passed since last update.

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

Posted at

LaavelからAWS S3へ画像をアップロードする方法をまとめました。

前提条件

AWS S3でユーザ登録とバケットの作成ができていること。
※AWS S3の設定はRails, Laravel(画像アップロード)向けAWS(IAM:ユーザ, 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の実装

今回は単純にcreateアクションでS3へアップロードします。
最低限のコードは次節以降になります。

アップロード処理

テーブルの作成

まずはデータベースにアップロード用のテーブルを作成するために、マイグレーションファイルを作成します。

php artisan make:migration create_posts_table

作成したマイグレーションファイルを以下のように編集します。

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            // 画像のパスを保存するカラムを追加
            $table->string('image_path')->nullable();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

マイグレーションを実行します。

php artisan migrate

以上でテーブルの作成は完了です。

Model

対応するModelを作成します。

php artisan make:model Post

View

/resources/views/post/create.blade.phpを作成します。
作成したファイルを以下のように編集します。

@section('content')
  <form action="{{ action('PostsController@create') }}" method="post" enctype="multipart/form-data">
    <!-- アップロードフォームの作成 -->
    <input type="file" name="image">
    {{ csrf_field() }}
    <input type="submit" value="アップロード">
  </form>
@endsection

Controller

Controllerを作成します。

php artisan make:controller PostsController

作成したControllerを以下のように編集します。

<?php

// 略

use App\Post;
use Storage;

class PostsController extends Controller
{
  public function add()
  {
      return view('posts.create');
  }

  public function create(Request $request)
  {
      $post = new Post;
      $form = $request->all();

      //s3アップロード開始
      $image = $request->file('image');
      // バケットの`myprefix`フォルダへアップロード
      $path = Storage::disk('s3')->putFile('myprefix', $image, 'public');
      // アップロードした画像のフルパスを取得
      $post->image_path = Storage::disk('s3')->url($path);

      $post->save();

      return redirect('posts/create');
  }
}

以上で、画像のアップロードは完成です。

実際にアップロードして、バケットへ画像がアップロードできていることを確認してください。
例:

3.png

画像の表示

ローカル画像を表示する場合とほとんど同じです。

View

/resources/views/post/index.blade.phpを作成し、以下のように修正します。

@section('content')
  @foreach($posts as $post)
    @if ($post->image_path)
      <!-- 画像を表示 -->
      <img src="{{ $post->image_path }}">
    @endif
  @endforeach
@endsection

Controller

Controllerに以下のようにindexアクションを追加します。

public function index(Request $request)
{
  $posts = Post::all();

  return view('posts.index', ['posts' => $posts]);
}

以上で、表示処理は完成です。

補足

うまく動作しない場合は、キャッシュをクリアしてみてください。

php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear

最後に

flysystem-aws-s3-v3パッケージを使用することで、手軽に画像のアップロードが可能でした。

参考

107
124
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
107
124