Laravelで画像投稿機能を実装します。具体的には以下のような機能を実装します。
上記の写真で画像ファイルを選択し、フォームにコメントを入力後、投稿ボタンを押すと、
上記の写真のように、画像とコメントを表示する機能を実装します。
#開発環境
Laravel:5.5.46
MYSQL:5.5.62
PHP:7.2.17
画像アップロードサーバ:AmazonS3
#マイグレーションファイル作成
画像とコメントを保存するためのテーブルpostsを作成します。ターミナルで以下のコマンドを実行しマイグレーションファイルを作成します。
$ php artisan make:migration _create_posts_table --create=posts
作成したマイグレーションファイルを編集します。
<?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
作成したモデルを編集します。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
//後にcreate()メソッドで保存するカラムを指定
protected $fillable = [
'image_file_name', 'image_title',
];
}
#ルータ
ルータを記述します。ページを表示したときと、投稿ボタンを押したときのルーティングを記述します。
Route::post('upload', 'PostsController@upload')->name('upload');
Route::get('/', 'PostsController@index');
#コントローラ
ターミナルで以下のコマンドを実行しコントローラを作成します。
$ php artisan make:controller PostsController
web.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で環境変数を設定します。
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を編集します。
//投稿フォーム
{!! 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