9
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Laravelで画像投稿機能を実装する

Posted at

Laravelで画像投稿機能を実装します。具体的には以下のような機能を実装します。

552fd9bc96fec88f5411232502dec300.png
上記の写真で画像ファイルを選択し、フォームにコメントを入力後、投稿ボタンを押すと、
a063c3be9f1d7d7c178c88822d409816.png

上記の写真のように、画像とコメントを表示する機能を実装します。

#開発環境
Laravel:5.5.46
MYSQL:5.5.62
PHP:7.2.17
画像アップロードサーバ:AmazonS3

#マイグレーションファイル作成
画像とコメントを保存するためのテーブルpostsを作成します。ターミナルで以下のコマンドを実行しマイグレーションファイルを作成します。

$ php artisan make:migration _create_posts_table --create=posts

作成したマイグレーションファイルを編集します。

database/migrations/2019_10_22_220848_create_posts_table.php
<?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_file_name',100);//追加
            $table->string('image_title',100);//追加
            $table->timestamps();
            
        });
    }

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

ターミナルで以下のコマンドを入力しマイグレーションを実行します。

$ php artisan migrate

#モデル

Postモデルを作成します。ターミナルで以下のコマンドを実行しモデルを作成します。

$ php artisan make:model Post

作成したモデルを編集します。

app/Post.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
//後にcreate()メソッドで保存するカラムを指定
    protected $fillable = [
        'image_file_name', 'image_title',
    ];
}

#ルータ
ルータを記述します。ページを表示したときと、投稿ボタンを押したときのルーティングを記述します。

routes/web.php
Route::post('upload', 'PostsController@upload')->name('upload');
Route::get('/', 'PostsController@index');

#コントローラ
ターミナルで以下のコマンドを実行しコントローラを作成します。

$ php artisan make:controller PostsController

web.phpに記述した各ルーティングに対応したアクションを記述します。

/app/Http/Controllers/PostsController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Foundation\Auth\User;
use App\Post;
use Storage;
use Illuminate\Support\Facades\Validator;

class PostsController extends Controller
{
//画像およびコメントアップロード
public function upload(Request $request){
        
//Validatorファサードのmakeメソッドの第1引数は、バリデーションを行うデータ。
//第2引数はそのデータに適用するバリデーションルール
        $validator = Validator::make($request->all(), [
            'file' => 'required|max:10240|mimes:jpeg,gif,png',
            'comment' => 'required|max:191'
        ]);
        
//上記のバリデーションがエラーの場合、ビューにバリデーション情報を渡す
        if ($validator->fails()){
            return back()->withInput()->withErrors($validator);
        }
//s3に画像を保存。第一引数はs3のディレクトリ。第二引数は保存するファイル。
//第三引数はファイルの公開設定。
        $file = $request->file('file');
        $path = Storage::disk('s3')->putFile('/', $file, 'public');
//カラムに画像のパスとタイトルを保存
        Post::create([
            'image_file_name' => $path,
            'image_title' => $request->comment
        ]);
   
        return redirect('/');
    }
//ページ表示
    public function index(){
        $posts = \App\Post::all();
    
        $data = [
            'posts' => $posts,
        ];
     
        return view('welcome',$data);
    }
}

ターミナルで以下のコマンドを入力し、ビューでFormファサードを使用できるようにします。

$ composer require "laravelcollective/html":"5.5.*"

AWSの S3にアクセスするライブラリを導入します。
$ composer require league/flysystem-aws-s3-v3

.envで環境変数を設定します。

.env

AWS_S3_KEY=[your Access Key ID]
AWS_S3_SECRET=[your Secret Key]
AWS_S3_REGION=[your region]
AWS_S3_BUCKET=[your backet]

#ビュー
resources/viewsに最初からあるwelcome.blade.phpを編集します。

resources/views/welcome.blade.php
//投稿フォーム
{!! Form::open(['route' => 'upload', 'method' => 'post','files' => true]) !!}
    <div class="form-group">
        {!! Form::label('file', '画像投稿', ['class' => 'control-label']) !!}
        {!! Form::file('file') !!}
    </div>
    <div class="form-group m-0">
        {!! Form::label('textarea', '投稿コメント', ['class' => 'control-label']) !!}
        {!! Form::textarea('comment',null,['class' => 'form-control']) !!}
    </div>   
    <div class="form-group text-center">
        {!! Form::submit('投稿', ['class' => 'btn btn-primary my-2']) !!}
    </div>
{!! Form::close() !!}
//画像とコメントをすべて表示
@foreach($posts as $post)
    <div class="card-header text-center">
        <img src= {{ Storage::disk('s3')->url($post->image_file_name) }} alt="" width=250px height=250px></a>
    </div>
    <div class="card-body p-1">
        <span class="card-title">{{ $post->image_title }}</span>
    </div>
@endforeach
9
9
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
9
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?