この記事でブラウザから画像をajaxでサーバー側へ届けることができたので、
今後はサーバー側の処理を実装します。
全部のコードを載せると長くなるので大事だと思うところだけにしています。
そのため以下のコードだけでは動きません💦
流れ

とても簡単な図ですが、青色枠がサーバー側の処理になります。
- 受け取った画像をstorageに保存
- 画像のパスを一時保存データ用テーブルへ保存
- そのレコードidをブラウザへ返却
- ブラウザで登録ボタンをクリック
- 本登録処理
②③画像をstorageへ、パスを一時テーブルへ
図の②、③の部分を実装します。
public function ajaxStoreImage(Request $request) { $img = $request->file('image'); // storage/app/img に画像本体を保存 $path = $img->store('img'); // tpmImgテーブルに画像パスを入れ,IDを取得 $tmpImg = $this->tmpImg->create([ 'path' => $path, ]); return response()->json( [ 'id' => $tmpImg->id, ] ); }
storageとTmpImgテーブルへデータを保存し、最後にjsonをreturnしています。
要件次第なので画像はpublic配下に保存してもいいのですが、
今回はまだ本登録していない画像は storage/app/img へ保存することにしました。
(publicでないのでブラウザからアクセスできない)
$path = $img->store('img');
laravelのstoreメソッドを使うことで、画像にオリジナルの名前をつけて保存し、最後にパスを返却してくれます!
返却されたパスは
/img/ljrk3fEH2VdNmUabOFlkh7FtyzHSxOjwpjHncfyH.png
こんな感じになっているので、それをTmpImgテーブルに保存。id(ここでは1)を返却します。
ここまでの段階で、画像自体はStorage/img配下に、パスはDBに保存されました。
④IDを元に画像を表示
phpからjsへidが返ってきたので、これをattrなどで imgタグに組み込みます(jsは省略)。
<img src="'/get-tmp-img/1"> // idが組み込まれた
/get-tmp-img の部分は任意なので何でも良いです。
そして、このurlがsrcに組み込まれると、今度は定義していたルーティングが動きます。
Route::get('/get-tmp-img/{tmpImg}',function(TmpImg $tmpImg) { return response()->file(Storage::path($tmpImg->path)); });
web.phpに、/get-tmp-img/{tmpImg} でアクセスがあった場合の処理をこんな風に定義していました。
function(TmpImg $tmpImg)
ここでは、imgタグのsrcに書かれていたidを$tmpImgとしてRouteの第二引数で使用。TmpImgのインスタンスを受け取っています。
return response()->file(Storage::path($tmpImg->path));
そして、最後はファイルレスポンス機能でパスを元にファイルを返却し、ブラウザで画像を表示しています。
たった3行ですが、なんだかすごいですね。。
⑤本登録処理
ブラウザでぽちっと登録ボタンを押せば、あとは普通の登録処理となります。
必要データを本登録用テーブルに保存
本登録データは実際には他にもあるのですが、画像の部分だけにして後はできるだけはしょっています。
// コントローラー内 public function store(Request $request) { //略 DB::transaction(function () { $imgPaths = $this->tmpImg->find([ //画像を三つまでアップロードできる仕様 Session::get('form-input.hidden-image.0'), Session::get('form-input.hidden-image.1'), Session::get('form-input.hidden-image.2'), ])->pluck('path'); $sessions = Session::get('form-input'); // その他の必要データ $review = $this->review->createReview($imgPaths, $sessions); //保存処理はModelで }); // 画像をpublicへ移動 // 不要なデータは削除 } //Model内 public function createReview(\Illuminate\Support\Collection $imgPaths, $sessions) { return self::create([ //略 'image_path_01' => $imgPaths[0] ?? null, //nullを許容しているのでデータなければnull 'image_path_02' => $imgPaths[1] ?? null, 'image_path_03' => $imgPaths[2] ?? null, ]); }
説明なくsessionとか出てきてすみません、、
確認画面を経る仕様なので、入力データはセッションで管理しています。
単純に画像パスをセッションから取得して、本登録テーブルに保存しています。
画像データをpublic配下に
本登録した画像はブラウザからアクセスできるよう、storage/public/配下に移動します。
public function moveImageToPublic(int $id = null) { if ($id === null) { return null; } $path = $this->tmpImg->find($id)->path; Storage::move($path, 'public/' . $path); return $path; } 現在のパスにpublic/をプラスして、同じstorageディレクトリ内で引越しします。 そして新しいパスを返却。
不要なDB、storageデータを削除
こちらはTmpImgModelに記述しています。
public function deleteImage(int $id) { $tmpImg = self::find($id); if (Storage::exists($tmpImg->path)) { Storage::delete($tmpImg->path); } $tmpImg->delete(); }
最初に保存したstorage(publicでない)に画像が残っていれば削除、
続いて一時保存テーブルのレコードを削除。