Help us understand the problem. What is going on with this article?

[Laravel] ユーザーのアイコン画像を投稿、表示させる機能の実装したのでメモ(画像の保存場所は?シンボリックリンクって?)

More than 1 year has passed since last update.

やりたいこと

Laravel で勉強のために簡単な CRUD アプリを作成中です。
ユーザーが自分のアイコン画像を投稿できる機能を実装しました。
ためになった知識や注意点などを自分用に備忘録としてメモします。

キャプチャ.PNG
こんな感じのイメージです。

画像はどのディレクトリに保存すればいいの?

コントローラーで受け取った画像などのファイルですが、基本的に storage/app/public 内に保存するようです。
(ただし、public ディレクトリに入っているファイルは誰でもアクセスできてしまうため、公開したくないファイルの場合は別途処理が必要みたいです。)

UserController.php
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_imagestore('public') とすることで public ディレクトリに保存してます。

config 内の filesystems.php を確認するとディスクの設定が確認できます。初期設定では storage/app ディレクトリに保存されるようになっているので、public ディレクトリに保存するために store メソッドの引数にディレクトリ名 public を指定します。

また、どの画像がどのユーザーのアイコンなのかを識別するために、ファイル名をユーザーテーブルに保存しています。store メソッドの戻り値としてファイルのパスが渡されるため、そのパスをユーザーテーブルの image カラムに保存します。その際、パス名が public/xxxxxxxxxx.jpg となるので不要な public/ の部分を削除しています。

シンボリックリンクって?

Laravel で作ったアプリケーションが公開されるとき、公開されるのは一番上の階層にある public ディレクトリのみです。public ディレクトリにファイルや処理のすべてが集約されています。なので、保存した画像も public ディレクトリ内に存在しないとアクセスすることができません。そこでシンボリックリンクを利用して storage ディレクトリにアクセスできるようにします。

キャプチャ.PNG

今回初めてシンボリックリンクとうい単語を知りました。
といっても特に難しいものではなく、UNIX 系で使われるいわゆるショートカットのようなもののようです(厳密には違いがあるのかもしれませんが...)。

シンボリックリンクは Artisan コマンドで作成できます。

php artisan storage:link

キャプチャ.PNG

これで storege へのリンクができたので画像データへアクセスできます!
右側にちょこんとくっついてる矢印がリンクのマークかと思われます(画像は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 はシンボリックリンクのことですね。

キャプチャ.PNG

よし!成功~

今回は以上です。

u-dai
元営業マン。2018年よりエンジニアへと転職。学んだことをメモしていきたいと思います。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした