Laravel 5.7 で画像アップロード用フィールドを作成する方法
Laravel 5.7にて、画像アップロードようのフィールドを作成する方法を記載します。
今回やること
・画面とテーブルの修正
・既存のテーブルにフィールド追加
・bladeファイルの修正(画像アップロードフィールドを作成)
・Controllerの修正(ディレクトリに画像アップロード・データベースに画像のパスを保存)
・保存された画像を画面で表示する
・確認
前提
・Laravelが動く環境がすでにあること
・こちらの記事で作成した投稿フォームを利用
・Laravel のバージョンは5.7
完成動画はこちらです。
それでは始めます。
--- 🖥 ---
画面とテーブルの修正
投稿画面
今回はこちらの記事で作成した投稿フォームに、画像アップロードようのフィールドを作成するように変更します。
※現在の投稿フォームの画面
テーブル定義
テーブル定義は下記のようにします。以前のテーブルに「image_url」というフィールドを追加します。
※テーブル定義は「フィールド名 / 物理名 /データ型」の順で記載します。
id / コンテンツID / integer
title / タイトル / VARCHAR
content / コンテンツ / text
user_id / ユーザID /integer
created_at / 作成日 / TIMESTAMP
updated_at / 更新日 / TIMESTAMP
image_url/ イメージURL / VARCHAR ← NEW
※user_idは投稿者のユーザIDを自動で取得するようにします。
※↑PHPMyAdminで確認したテーブル
既存のテーブルにフィールド追加
それではまずは既存の「posts」テーブルに「image_url」フィールドを追加します。フィールドの追加はマイグレーションファイルを作成し行います。
1. マイグレーションファイルの作成
下記実行しマイグレーションファイルを作成します。
php artisan make:migration add_image_url_to_posts_table --table=posts
↑のポイント
・add_image_url_to_posts_table は 作成されるファイル名です。
・--table=posts には追加するテーブル名を記載します。
これで「database/migrations」ディレクトリに「2019_02_08_075440_add_image_url_to_posts_table.php」のようなファイルが作成されます。
(ファイル名の最初の2019_02_08_075440 は作成した日付です)
2. マイグレーションファイルの修正
作成された「2019_02_08_075440_add_image_url_to_posts_table.php」を修正します。
function up() に追加するフィールド情報を記載します。
public function up()
{
Schema::table('posts', function (Blueprint $table) {
$table->string('image_url');
});
}
また、function down() にはこの処理を巻き戻す際の処理を記載します。
public function down()
{
Schema::table('posts', function (Blueprint $table) {
$table->dropColumn('image_url');
});
}
以上でファイルの修正完了です。
3. マイグレーションを実行
それではマイグレーションを実行します。下記の実行してください。
php artisan migrate
無事実行されたらテーブルを確認します。PHPMyAdminで見ると、一番右に「image_url」が追加されています。
以上で既存のテーブルにフィールド追加は完成です。
bladeファイルの修正(画像アップロードフィールドを作成)
次にbladeファイルを修正し、画像アップロードフィールドを作成します。
今回は「resources/views/posts/create.blade.php」を修正します。
「タイトル」と「内容」の間にアップロード用のフィールドを追加します。
<div class="form-title">
<label for="title">タイトル</label>
<input class="" name="title" value="{{ old('title') }}">
</div>
<div class="form-image_url">
<input type="file" name="image_url">
</div>
<div class="form-content">
<label for="content" class="form-content">内容</label>
<textarea class="" name="content" cols="50" rows="10">{{ old('content') }}</textarea>
</div>
保存しブラウザで画面を確認すると画像アップロードようのフィールドが追加されています。
以上で表示は完成です。
・Controllerの修正(ディレクトリに画像アップロード・データベースに画像のパスを保存)
次に「PostController.php」を修正します。
今回は
・アップロードした画像はディレクトリに保存される。
・データベースにはアップロード先のパスが格納される。
という方法にて行います。
1. createメソッドの修正
PostController.phpのcreateメソッドに下記追加します。
$post->image_url = $request->image_url->storeAs('public/post_images', $time.'_'.Auth::user()->id . '.jpg');
↑のポイント
・画像の保存先は「storage/post_images」というディレクトリに格納されます
・ファイル名は「[投稿時間]_[ユーザid].jpg」となるようにリネームしてます。
・storeAs関数を利用して、ファイル名とディレクトリ名を指定するようにしています。
また補足として、Laravelの画像の置き場所の推奨は、
「public/images」配下に直接ファイルを置くのではなく、
「storage/app/public」配下に置き、
public/storageからstorage/app/publicにシンボリックリンクを貼り、そちらにアクセスすることを推奨しているようです。
(詳しくはこちらのページの「 パブリックディスク」の箇所を参照ください。)
そのため、今回のように「storage」ディレクトリ配下にアップするような手順が必要となります。
(後ほどシンボリックリンクの貼り方を説明します)
2. detailメソッドの修正
detailメソッドに下記のように修正します。
public function detail(Post $post)
{
return view('posts/detail', [
'title' => $post->title,
'content' => $post->content,
'user_id' => $post->user_id,
'image_url' => str_replace('public/', 'storage/', $post->image_url), //今回追加
]);
}
以上でControllerの修正は完了です。
保存された画像を画面で表示する
最後に保存された画像を画面で表示する方法を説明します。
まずは「storage/app」にアクセスするために、シンボリックリンクを貼ります。下記実行します。
php artisan storage:link
次に、「resources/views/posts/detail.blade.php」を下記のように修正します。
<p>タイトル:{{ $title }}</p>
<p>詳細内容:{{ $content }}</p>
<p>ユーザID:{{ $user_id }}</p>
@if ($image_url)
<p>画像:<img src ="/{{ $image_url }}"></p>
@endif
↑のポイント
・画像は必須項目ではないので、画像が投稿された場合のみ表示するようにif文で分岐しています。
以上で画像の表示処理について完成です。
確認
では実際に投稿フォームから画像を投稿してみましょう。
画像をアップロードすると↓のようにファイル名が表示されます。
「投稿する」をクリックすると画像が表示されます。
データベースを確認すると、フィールドには画像のパスが保存されています。
以上で完成です。お疲れ様でした!
GitHubリポジトリ
今回作成したソースはGithubにて公開しています。下記リンクよりご確認ください。(lerning-4ブランチです。)
https://github.com/KoushiKagawa/laravel-learning/tree/learning-4
書き方の間違いや、もっとこう書いた方が良いよ!といったご指摘はコメント欄かtwitterのDMいただけると喜びます!
読んでいただきありがとうございます。