Laravelで投稿フォームに画像のアップロード機能を付ける方法を解説していきますね。
画像を保存するために、storeAs と getClientOriginalNameを使っていきます。
*バージョンはLaravel8を使っています。
画像アップロード機能を投稿フォームにつける【初心者のLaravel入門講座】
手順は次のとおりです。
- 画像のパスをいれるカラムをテーブルに作成する
- フォームの中に画像をアップロード機能を付ける
- シンボリックリンクを貼る
- コントローラーに画像保存処理を記述する
- 投稿テストをする
- 表示テストをする
①画像のパスをいれるカラムをテーブルに作成する
マイグレーションファイルに、画像のパスをいれるカラムを作っておきましょう。
$table->text('image');
前後の部分もあわせると、このような感じに作ります。
.jpg)
②フォームの中に画像をアップロード機能を付ける
フォームの中に画像をアップロードする機能を付けます。
<input id="image" type="file" name="image">
ブラウザで表示させると、このようなファイル選択ボタンができています。

③シンボリックリンクを貼る
次に、こちらのコマンドでシンボリックリンクを作成します。
シンボリックリンクとは、ショートカットのようなものです。
php artisan storage:link
コマンド実行後、publicフォルダ内にstorageフォルダへのリンクが貼られます。

なぜシンボリックリンクが必要なの?
シンボリックリンクはわかりにくいのですが、Laravelで画像を保存するうえで、わりと重要です。
デフォルトでは、画像はstorageフォルダ内に保存されます。
ですがLaravelのプロジェクトをWeb上に公開した時は、ユーザーはpublicフォルダのファイルにしかアクセスできません。
つまり、storageフォルダ内の画像がユーザーに表示されなくなってしまうのです。
シンボリックリンクを貼ることでstorageフォルダとpublicフォルダをつなげられ、この問題を回避できます。
④コントローラーに画像保存処理を記述する
最後に、コントローラーに画像を保存するコードを記述していきましょう。
画像ファイルのINPUTタグのname属性が【image】であるとします。
コントローラーには、下記のように記述します。
public function store(Request $request)
{
// 新規postを作成
$post=new Post();
// バリデーションルール
$inputs=request()->validate([
'title'=>'required|max:255',
'body'=>'required|max:255',
'image'=>'image'
]);
// 画像ファイルの保存場所指定
if(request('image')){
$filename=request()->file('image')->getClientOriginalName();
$inputs['image']=request('image')->storeAs('public/images', $filename);
}
// postを保存
$post->create($inputs);
画像の保存に関する記述は、次のように入れました。
$filenameで、ファイル名を指定しています。
元々のファイル名でファイルを保存するには、getClientOriginalNameを使います。
保存するために、storeAsを使用しています。
⑤投稿テストをする
それでは、実際にフォームに画像を入れて投稿をしてみます。

フォームを送信した後、データベースには次のように保存されました。

⑥表示テストをする
最後に、保存された画像ファイルをimg srcタグに埋め込み、ブラウザに表示してみます。
bladeファイルには、次のように記述しました。
@foreach($posts as $post)
<img src="{{ Storage::url($post->image)}}" width="100px">
@endforeach
ブラウザには、下記のように表示されました。

さいごに
無事に画像が表示されましたか?
画像表示は、ちょっとしたことで、うまくいかなかったりします(←経験則)
もしうまくいかなかった場合は、下記の点をチェックしてください。
- ローカルフォルダをチェック:フォルダにちゃんとファイルが保存されているか
- ブラウザのソースコードをチェック:ブラウザのパスは正しく入っているか
必要に応じて、保存場所やパスの指定を変えてくださいね。


コメント