Quantcast
Channel: 初心者タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 21093

AWS S3 Laravelアプリから画像ファイルをアップロードして表示する

$
0
0

目次

  • AWS EC2に構築したLaravel環境で作成したLaravelアプリから画像ファイルをS3にアップロードする方法をまとめる

実施環境

  • ハードウェア環境
項目情報
OSmacOS Catalina(10.15.5)
ハードウェアMacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)
プロセッサ2 GHz クアッドコアIntel Core i5
メモリ32 GB 3733 MHz LPDDR4
グラフィックスIntel Iris Plus Graphics 1536 MB
  • ソフトウェア環境(下記の環境をEC2に構築した)
項目情報備考
MySQL8.0.20 for Linux on x86_64コマンド$ mysql --versionで確認
Apache2.4.43コマンド$ httpd --versionで確認
PHP7.4.5コマンド$ php --versionで確認

前提条件

読後感

  • AWS EC2にてデプロイしたLaravelアプリからのトリガーで画像ファイルをS3の「test」のフォルダ直下に保存することができる。

概要

  1. S3にてバケットを作成
  2. アクセスキーの取得
  3. テーブルの作成
  4. ファイル設置処理の付与
  5. 設定

詳細

  • 下記の説明で使用するコマンドはsshでインスタンスに接続して実行する物とする。
  1. S3にてバケットを作成
    1. 下記のリンクの手順を実施してS3にバケットを作成する。(testフォルダの作成まで実施する。)
  2. アクセスキーの取得
    1. 下記のリンクの手順を実施してアクセスキーとシークレットアクセスキーの取得を行う。
  3. Laravelアプリ側の設定

    1. 下記コマンドを実行してApacheのドキュメントルートまで移動する。

      $cd /var/www/html/
      
    2. 下記コマンドを実行してスワップ領域の値を設定する。(/bin/dd: failed to open ‘/var/swap.1’: Text file busyと出力されてしまった方はAWSのEC2コンソールより一旦インスタンスを再起動する。Linuxの物理マシンで実施中の方もLinux物理マシンを再起動する。※インスタンス再起動後はssh接続のコマンドが変化するため注意する。)

      $sudo /bin/dd if=/dev/zero of=/var/swap.1 bs=1M count=1024
      $sudo /sbin/mkswap /var/swap.1
      $sudo /sbin/swapon /var/swap.1
      
    3. sshを用いてインスタンスに接続し、下記コマンドを実行してライブラリのインストールを行う。(エラーThe following exception is caused by a lack of memory or swap, or not having swap configuredが発生した方はこちら→composerを用いたインストール中にメモリ系のエラーが出た話)

      $cd /var/www/html/test
      $composer require league/flysystem-aws-s3-v3 ~1.0
      
    4. 下記コマンドを実行してLaravelの設定ファイルを開く。

      $vi .env
      
    5. 下記の様に設定ファイルを修正する。

      • 修正前

        /var/www/html/test/.env
        AWS_ACCESS_KEY_ID=
        AWS_SECRET_ACCESS_KEY=
        AWS_DEFAULT_REGION=us-east-1
        AWS_BUCKET=
        
      • 修正後

        /var/www/html/test/.env
        AWS_ACCESS_KEY_ID=AWSのアクセスキーを記載する
        AWS_SECRET_ACCESS_KEY=AWSのシークレットアクセスキーを記載する
        AWS_DEFAULT_REGION=ap-northeast-1
        AWS_BUCKET=先に作成したバケット名
        
      • 修正後の.envファイルの全体を下記に記載する。

        /var/www/html/test/.env
        APP_NAME=test
        APP_ENV=local
        APP_KEY=base64:ZJYPq8Ij/UIWowQG+H4Gwz+zXjs/vEn85Yfv45qQa88=
        APP_DEBUG=true
        APP_URL=http://localhost
        
        LOG_CHANNEL=stack
        
        DB_CONNECTION=mysql
        DB_HOST=127.0.0.1
        DB_PORT=3306
        DB_DATABASE=test
        DB_USERNAME=root
        DB_PASSWORD=**************
        
        BROADCAST_DRIVER=log
        CACHE_DRIVER=file
        QUEUE_CONNECTION=sync
        SESSION_DRIVER=file
        SESSION_LIFETIME=120
        
        REDIS_HOST=127.0.0.1
        REDIS_PASSWORD=null
        REDIS_PORT=6379
        
        MAIL_MAILER=smtp
        MAIL_HOST=smtp.mailtrap.io
        MAIL_PORT=2525
        MAIL_USERNAME=null
        MAIL_PASSWORD=null
        MAIL_ENCRYPTION=null
        MAIL_FROM_ADDRESS=null
        MAIL_FROM_NAME="${APP_NAME}"
        
        AWS_ACCESS_KEY_ID=AWSのアクセスキーを記載する
        AWS_SECRET_ACCESS_KEY=AWSのシークレットアクセスキーを記載する
        AWS_DEFAULT_REGION=ap-northeast-1
        AWS_BUCKET=先に作成したバケット名
        
        PUSHER_APP_ID=
        PUSHER_APP_KEY=
        PUSHER_APP_SECRET=
        PUSHER_APP_CLUSTER=mt1
        
        MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
        MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
        
  4. テーブルの作成

    1. アプリ名ディレクトリで下記コマンドを実行してS3に格納する画像ファイルのパスとログイン中のユーザIDを格納するimagesテーブルを作成するマイグレーションファイルとモデルファイルを作成する。

      $php artisan make:model Image --migration
    2. 下記にファイルが作成された事を確認する。

      • アプリ名ディレクトリ/app/Image.php
      • アプリ名ディレクトリ/database/migrations/YYYY_MM_DD_XXXXXX_create_images_table.php
    3. アプリ名ディレクトリで下記コマンドを実行してマイグレーションファイルを開く。

      $vi database/migrations/YYYY_MM_DD_XXXXXX_create_images_table.php
      
    4. 開いたマイグレーションファイルを下記の様に記載する。

      アプリ名ディレクトリ/database/migrations/YYYY_MM_DD_XXXXXX_create_images_table.php
      <?phpuseIlluminate\Database\Migrations\Migration;useIlluminate\Database\Schema\Blueprint;useIlluminate\Support\Facades\Schema;classCreateImagesTableextendsMigration{/**
           * Run the migrations.
           *
           * @return void
           */publicfunctionup(){Schema::create('images',function(Blueprint$table){$table->id();//下記を追記する$table->foreignId('user_id');$table->string('path');//上記までを追記する$table->timestamps();});}/**
           * Reverse the migrations.
           *
           * @return void
           */publicfunctiondown(){Schema::dropIfExists('images');}}
    5. アプリ名ディレクトリで下記コマンドを実行してマイグレーションを行う。

      $php artisan migrate
      
  5. ファイル設置処理の付与

    1. アプリ名ディレクトリで下記コマンドを実行してルーティングファイルを開く。

      $ vi routes/web.php
      
    2. 開いたルーティングファイルを下記の様に修正する。(そのほかのルーティング情報が下記記載と一致していなくても追記部分だけ追記する。)

      アプリ名ディレクトリ/routes/web.php
      <?phpuseIlluminate\Support\Facades\Route;/*
      |--------------------------------------------------------------------------
      | Web Routes
      |--------------------------------------------------------------------------
      |
      | Here is where you can register web routes for your application. These
      | routes are loaded by the RouteServiceProvider within a group which
      | contains the "web" middleware group. Now create something great!
      |
      */Route::get('/',function(){returnview('welcome');});Auth::routes();Route::get('/home','HomeController@index')->name('home');//下記を追記//画像ファイルをアップロードするボタンを設置するページへのルーティングRoute::get('/upload/image','ImageController@input');//画像ファイルをアップロードする処理のルーティングRoute::post('/upload/image','ImageController@upload');//アップロードした画像ファイルを表示するページのルーティングRoute::get('/output/image','ImageController@output');//上記までを追記
    3. アプリ名ディレクトリで下記コマンドを実行してコントローラファイルを作成する。

      $php artisan make:controller ImageController
      
    4. 下記のコントローラファイルが作成される。

      • アプリ名ディレクトリ/app/Http/Controllers/ImageController.php
    5. アプリ名ディレクトリで下記コマンドを実行してコントローラファイルを開く。

      $vi app/Http/Controllers/ImageController.php
      
    6. 開いたコントローラファイルを下記の様に修正する。

      アプリ名ディレクトリ/app/Http/Controllers/ImageCotroller.php
      <?phpnamespaceApp\Http\Controllers;useIlluminate\Http\Request;//下記を追加するuseIlluminate\Support\Facades\Auth;useIlluminate\Support\Facades\Storage;classImageUploadControllerextendsController{//下記を追加publicfunctioninput(){returnview('images.input');}publicfunctionupload(Request$request){$this->validate($request,['file'=>[// 必須'required',// アップロードされたファイルであること'file',// 画像ファイルであること'image',// MIMEタイプを指定'mimes:jpeg,png',]]);if($request->file('file')->isValid([])){//バリデーションを正常に通過した時の処理//S3へのファイルアップロード処理の時の情報を変数$upload_infoに格納する$upload_info=Storage::disk('s3')->putFile('/test',$request->file('file'),'public');//S3へのファイルアップロード処理の時の情報が格納された変数$upload_infoを用いてアップロードされた画像へのリンクURLを変数$pathに格納する$path=Storage::disk('s3')->url($path);//現在ログイン中のユーザIDを変数$user_idに格納する$user_id=Auth::id();//モデルファイルのクラスからインスタンスを作成し、オブジェクト変数$new_image_dataに格納する$new_image_data=newImage();//プロパティ(静的メソッド)user_idに変数$user_idに格納されている内容を格納する$new_image_data->user_id=$user_id;//プロパティ(静的メソッド)に変数$pathに格納されている内容を格納する$new_image_data->path=$path;//インスタンスの内容をDBのテーブルに格納する$new_image_data->save();returnredirect('/');}else{//バリデーションではじかれた時の処理returnredirect('/upload/image');}}publicfunctionoutput(){//現在ログイン中のユーザIDを変数$user_idに格納する$user_id=Auth::id();//imagesテーブルからuser_idカラムが変数$user_idと一致するレコード情報を取得し変数$user_imagesに格納する$user_images=Image::whereUser_id($user_id)->get();returnview('images.output',['user_images'=>$user_images]);}//上記までを追記}
    7. アプリ名ディレクトリで下記コマンドを実行してビューファイルを格納するディレクトリを作成する。

      $mkdir resources/views/images
      
    8. アプリ名ディレクトリで下記コマンドを実行してビューファイルを作成する。

      $touch resources/views/images/input.blade.php
      $touch resources/views/images/output.blade.php
      
    9. アプリ名ディレクトリで下記コマンドを実行して画像をアップロードするビューファイルを開く。

      $vi resources/views/images/input.blade.php
      
    10. 開いたビューファイルを下記の様に記載する。

      アプリ名ディレクトリ/resources/views/images/input.blade.php
      @extends('layouts.app')
      
      @section('content')
      
      <!-- トリガー -->
      <form action="/upload/image" method="POST" enctype="multipart/form-data">
          @csrf
      
          <label for="photo">画像ファイル:</label>
          <input type="file" class="form-control" name="file">
          <br>
          <input type="submit">
      </form>
      @endsection
      
    11. アプリ名ディレクトリで下記コマンドを実行して画像をアップロードするビューファイルを開く。

      $vi resources/views/images/output.blade.php
      
    12. 開いたビューファイルを下記の様に記載する。

      アプリ名ディレクトリ/resources/views/images/output.blade.php
      @extends('layouts.app')
      
      @section('content')
          <a href="/upload">画像のアップロードに戻る</a>
          <br>
          @foreach ($user_images as $user_image)
              <img src="{{ $user_image['path'] }}">
              <br>
          @endforeach
      @endsection
      
  6. 確認

    1. ブラウザからAWSの下記のページ(コンソール)にアクセスする。

      インスタンス___EC2_Management_Console_と_ec2-user_ip-172-31-9-5__.png

    2. 「接続」をクリックする。

      インスタンス___EC2_Management_Console.png

    3. 下記画像の矢印が指しているURLをコピーして別のブラウザのURL入力欄に貼り付ける。

      インスタンス___EC2_Management_Console.png

    4. 下記のページが表示されることを確認する。

      Laravel.png

    5. 先に表示したLaravelアプリのホーム画面のURLに/upload/imageを末尾に追記したURLにアクセスし、先にに作成したファイルを送信するトリガーのボタンが存在するページを表示する。

      Laravel.png

    6. 任意の画像ファイルを選択し「送信」ボタンを押下する。(送信ボタン押下後にエラーが403エラーが発生する場合は.envファイルの記載に誤りがあることが多い)

      Laravel.png

    7. S3のバケットのテストファイル直下に下記の様にファイルが格納されていることを確認する。(ファイル名はランダムになる。)

      S3_Management_Console_と_ec2-user_ip-172-31-12-2__var_www_html_test_と_下書き一覧_-_Qiita_と_credentials__1_.png

    8. 先に表示したLaravelアプリのホーム画面のURLに/output/imageを末尾に追記したURLにアクセスし、先にアップロードした画像が表示されていることを確認する。

参考文献


Viewing all articles
Browse latest Browse all 21093

Trending Articles