背景
Laravelでの画像取得処理を実装したときの個人的メモです。
画像の保存方法
- 画面などからアップした画像を保存する
- インターネット上に保存されている画像を保存する
画像の保存先
以下2つが考えられるが、2.の方がメジャーなようなのでそちらで実装する。
- 画像ファイルをDBにそのままバイナリデータとして保存する
- 画像ファイルはサーバ上に保存しておきDBにはファイル格納パスだけを保存する
1. 画面からアップした画像を保存する(アバター画像をアップロードする)
upload.blade.php
<form method="post" action="{{route('profile.update', $user)}}" enctype="multipart/form-data">
@csrf
@method('put')
<div class="form-group">
<label for="avatar">アバター</label>
<!-- ↓登録済みファイルの表示。 -->
<img src="{{asset('storage/avatar/'.($user->avatar))}}"
class="d-block rounded-circle mb-3" style="height:100px;width:100px;">
<div>
<!-- ↓ファイルアップロード用UI。バックエンドではこれをオブジェクトとして利用可能 -->
<input id="avatar" type="file" name="avatar">
</div>
</div>
profilecontoroller.php
public function update(User $user, Request $request){
// ...中略
// リクエストオブジェクトのfileメソッドでname="avatar"を取得し、アップロード時に指定したオリジナルの名称を取得
$name=request()->file('avatar')->getClientOriginalName();
// リクエストオブジェクトのfileメソッドでname="avatar"を取得し、storeAsメソッドで名前を付けて画像ファイルをサーバに登録。引数はパス、ファイル名。
request()->file( 'avatar')->storeAs('public/avatar', $name);
$inputs['avatar'] = $name;
// 保存したファイルパスをDBに更新
$user->update($inputs);
2. インターネット上に保存されている画像を保存する
画像ファイルの保存先URLがDBに格納されており、それを使って画像ファイルを取得・保存し、DBにパスを更新する。という場合。
profilecontoroller.php
use Illuminate\Support\Facades\Storage;
// 中略...
////////////////
// 画像データ取得
////////////////
// $image = Storage::get($image_url); //これはエラーになる。Laravelが管理する範囲内しか取得できない。Laravel独自の関数は無いようなのでphpのfile_get_contentsを使う。
$image = file_get_contents($image_url);
////////////////
// 画像データ保存
////////////////
// 画像ファイルパスを作成。$image_idは一意の名前が格納されている。
$image_path = 'Images/' . $image_id . '.jpeg';
// Storage Facadeを使い、ドライバを指定してファイルを保存。ドライバの指定なしだとデフォルトのLOCALドライバが使われる。ストレージドライバはconfig/filesystems.phpの設定による。
Storage::disk('public')->put($image_path , $image);
// DBカラムに画像ファイルパスを更新。$userはuserモデル。
$user->image_file_path = $image_path;
$user->save();
Laravelには大抵の処理にはヘルパ関数があるので
phpオリジナル関数のfile_get_contents
をつかわないとできないところが
個人的に引っかかりました。
何かベストプラクティスあれば教えて頂けると幸いです。