Laravel Vue.jsで画像をアップロード DB保存までの流れ

2020年2月22日

PHP

LaravelとVue.jsを利用し、画像をアップロードし表示させる機能をSPA(Single Page Application)で実装します。

 

 

作成するアプリケーションの概要


 

下記イラストのように、タイトルと画像を登録するアプリケーションを作成します。LaravelでAPIを作成し、フロント側はVue.jsで構築しています。本記事では画像ファイル自体のアップロード先はLaravelのプロジェクト内(ローカルストレージ)で、そのパスのみをDBに保存しています。

 

 

1,初期状態です。

2,タイトル未入力およびファイルを選択せずに「アップロード」ボタンをクリックした場合のエラーメッセージです。バリデーションはAPI側で処理されています。

3,「ファイルを選択」で画像形式以外のファイルを選択した場合のエラーメッセージです。バリデーションはVue.js側で処理しています。

4,文字は7文字以内で設定しています。タイトルのバリデーションはAPI側のみで検証しています。

5,タイトルと画像の保存先パスがDBに登録されると「登録しました!」と表示され、下に表示されます。

 

今回、フロント側のバリデーションは画像形式の検証時のみにおこなっています。エラー処理周りの挙動も画面仕様により変わってくるので簡易的に処置していますが、サーバー側からVue.jsへのエラーメッセージの渡し方などの一連の動きは理解できるかと思います。

 

 

API側の実装


 

あらかじめデータベースを用意しておいて下さい。本記事ではMySQLを利用します。.envに適当な値を設定します。

 

.env

 

画像ファイルのパスとタイトルを保存するテーブルを作成します。

 

モデルとマイグレーションファイルを作成します。

 

以上でimagesテーブルに対応したモデル(app/Image.php)とマイグレーションファイルが生成されるので、それぞれ下記のように追記します(ハイライト部分)。

 

app/Image.php

 

 

database/migrations/2020_02_23_124607_create_images_table

 

マイグレーションを実行します。

 

完了するとimagesテーブルが生成されているのが確認できます。

 

 

コントローラーの作成


 

–apiを付けてコントローラーファイルを作成します。 

 

api.phpに下記コードを追記します。/api/images/〜というエンドポイントになります。

routes/api.php

 

設定されているルート情報を確認します。

 

生成されたコントローラーファイルにはすでにいくつかのメソッドが用意されていますが、今回は表示と保存の機能のみを実装するので index() / store() を利用します。

 

app/Http/Controllers/ImageApiController.php

39行目

storeへは後述するVue.js側から、画像ファイル(file)とタイトル(title)の2つのデータが送られてきますが、getClientOriginalNameメソッドでそのファイル名を取得し、今回はタイムスタンプをその名前に付与しています。

 

40行目

またstoreAsメソッドでLaravelのプロジェクト内にファイルを保存しています。デフォルトでは storage/app/public ディレクトリ内に画像を保存するようにします。ただし後述するようにこのstorage/app/publicは、ウェブ(ブラウザ)からはアクセスできないのでシンボリックリンクを公開ディレクトリであるpublic/storageから貼る必要があります。

 

 

 

フロント側の実装


 

Laravelのバージョン6.xでVue.jsをはじめて利用する方は下記ページをご覧下さい。

Laravel 6 Vue.jsを利用する [axios][Laravel Mix]

 

まずlaravel/uiパッケージをインストールします。

 

Vue.jsで構築するためのファイル等を生成します。

 

package.jsonの内容に依存したパッケージをインストールし、コンパイルします。

 

 
Vueコンポーネント(後述)関連のファイルを編集/保存した際には「npm run dev」で再度コンパイルする必要がありますが、watchでそれら編集/保存を監視しコンパイルを自動化することができます。

 

サーバーを起動させます。

 

画面を作成していきます。「http://localhost:8000/image」としての一画面のSPAとなります。コントローラーを作成し、ルート情報に追記、後述のようにコントローラーを編集します。

 

routes/web.php

 

app/Http/Controllers/ImageController.php

 

 

ビュー(テンプレート)を作成します。imageupディレクトリおよびindex.blade.phpを作成し下記のように記述します。

resources/views/imageup/index.blade.php

13行目

image-componentという名前のVueコンポーネントを表示させます。

 

 

app.jsに下記コードを追記して下さい。

resources/js/app.js

image-componentという名前のコンポーネントに対して下記で作成するImageComponent.vueを割り当てています。

 

ImageComponent.vueを作成し下記のように記述します。一番右のアイコンをクリックするとコードが別ウィンドウで開いて説明が読みやすいです。

resources/js/components/ImageComponent.vue

4行目

v-if=”view”は、「アップロード」ボタンをクリックした後に「ファイルを選択」ボタンの横のファイル名を初期化する処置を実装しています(89~92行目)。
 
 
59〜64行目
読み込んだファイルの情報を取得しています。これら情報から容量等を取得しファイルの検証をおこなうことができます。上記ではMIMEタイプで画像ファイルかどうかを判定しています。下記関連ページもご覧下さい。
 

CSVファイルを読み込み表示

 

68〜72行目

FileReaderのインスタンスを作成しfileを読み込んでいます。画像の場合はreadAsDataURLを利用し読み込みます。読み込み完了と同時にonloadが発動します。

 

75〜77行目

Laravel側のapiへPOSTするデータとしてFormData オブジェクトを利用し、fileと画像データ/titleとタイトルというキーと値のペアを作成しています。

 

79〜96行目

axiosに関しては下記ページをご覧下さい。登録が成功するとgetImage()によってデータが画面下に表示されます。

axiosでJSONを取得する[Vue.js]

 

 

コンポーネントの実装は以上です。最後にシンボリックリンクを貼って完了です。

 

 

シンボリックリンク


 

Laravelのデフォルト設定では、ファイルはstorage/app/public以下に保存し、ここにウェブ(ブラウザ)からアクセスできるようにします。そのためには公開ディレクトリであるpublic/storageから storage/app/public へシンボリックリンクを貼る必要があります。

 

下記コマンドを実行します。

 

コマンドを実行すると下記URLのようにして画像が確認できます。

 

本記事では説明はしませんが、これらファイルストレージの設定は config/filesystems.php(.env)に記述されていて、AWSのS3等へのファイル保存の設定も可能です。

 

関連ページ

AWS S3にファイルをアップロード

 

 

 

参照ページ


 

Laravel 6.x ファイルストレージ

 

 

 

LINEで送る
Pocket

定番本
定期本
 
Copyright © 2020 思考の葉 All Rights Reserved.  プライバシーポリシー