#やりたいこと
Laravel で勉強のために簡単な CRUD アプリを作成中です。
ユーザーが自分のアイコン画像を投稿できる機能を実装しました。
ためになった知識や注意点などを自分用に備忘録としてメモします。
#画像はどのディレクトリに保存すればいいの?
コントローラーで受け取った画像などのファイルですが、基本的に storage/app/public
内に保存するようです。
(ただし、public ディレクトリに入っているファイルは誰でもアクセスできてしまうため、公開したくないファイルの場合は別途処理が必要みたいです。)
public function image(Request $request, User $user) {
// バリデーション省略
$originalImg = $request->user_image;
if($originalImg->isValid()) {
$filePath = $originalImg->store('public');
$user->image = str_replace('public/', '', $filePath);
$user->save();
return redirect("/user/{$user->id}")->with('user', $user);
}
上記コントローラーでは <input type="file" name="user_image">
で送った画像ファイル $request->user_image
を store('public')
とすることで public ディレクトリに保存してます。
config 内の filesystems.php
を確認するとディスクの設定が確認できます。初期設定では storage/app
ディレクトリに保存されるようになっているので、public ディレクトリに保存するために store メソッドの引数にディレクトリ名 public を指定します。
また、どの画像がどのユーザーのアイコンなのかを識別するために、ファイル名をユーザーテーブルに保存しています。store メソッドの戻り値としてファイルのパスが渡されるため、そのパスをユーザーテーブルの image カラムに保存します。その際、パス名が public/xxxxxxxxxx.jpg
となるので不要な public/
の部分を削除しています。
#シンボリックリンクって?
Laravel で作ったアプリケーションが公開されるとき、公開されるのは一番上の階層にある public ディレクトリのみです。public ディレクトリにファイルや処理のすべてが集約されています。なので、保存した画像も public ディレクトリ内に存在しないとアクセスすることができません。そこでシンボリックリンクを利用して storage ディレクトリにアクセスできるようにします。
今回初めてシンボリックリンクとうい単語を知りました。
といっても特に難しいものではなく、UNIX 系で使われるいわゆるショートカットのようなもののようです(厳密には違いがあるのかもしれませんが...)。
シンボリックリンクは Artisan コマンドで作成できます。
php artisan storage:link
これで storage へのリンクができたので画像データへアクセスできます!
右側にちょこんとくっついてる矢印がリンクのマークかと思われます(画像はVSCode)。
#画像が表示されるか試してみる
作成したシンボリックリンクの中を見てみると、当然ですが storage/app/public
の中身がこんにちわしてます。以下のようにビューを編集すれば画像が表示させるはず!
@if($user->image == null)
<img src="/storage/noimage.png">
@else
<img src="/storage/{{$user->image}}">
@endif
ユーザーアイコンがなければ noimage.png
を表示、アイコンが登録されていればユーザーテーブルの image カラムからファイル名を引っ張ってきます。
<img>
タグの src=
につづくパス名は、一番上の階層の public ディレクトリがルートディレクトリになりますので、"/storage/xxxxxxxxx.jpg"
などとすることで画像へアクセスすることができます。この storage
はシンボリックリンクのことですね。
よし!成功~
今回は以上です。