この記事でブラウザから画像を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でない)に画像が残っていれば削除、
続いて一時保存テーブルのレコードを削除。


