storage下のファイルを読み込もうとしても、404エラーになってしまいます。
今回はこんな疑問に答えていきます。
【前提】
・laravel8
結論:Laravelでは、php artisan:storage linkでシンボリックリンクを貼らないとweb側から参照できない
結論から話すと、storage下のファイルを指定して表示させようとしても404で失敗してしまうのは、仕様上そうなっているからです。
以下のように、正しいパスを指定してassetで読み込もうとしても失敗します。
<img src="{{ asset("storage/app/public/logo.png") }}" >
解決策は「シンボリックリンク」を貼ることです。
Laravelはデフォルトでstrageはweb側から参照できない→シンボリックリンクを貼りましょう
なぜシンボリックリンクを貼るかなのですが、Laravelの仕様上、そうしないとweb側からstorage下のファイルにアクセスできない、ファイル規約があるからです。
アプリケーションの
filesystems
設定ファイルに含まれているpublic
ディスクは、パブリックに公開してアクセスできるようにするファイルを対象としています。デフォルトでは、public
ディスクはlocal
ドライバーを使用し、そのファイルをstorage/app/public
に保存します。これらのファイルにWebからアクセスできるようにするには、
public/storage
からstorage/app/public
へのシンボリックリンクを作成する必要があります。
ということで、以下のコマンドでシンボリックリンクを貼りましょう。
php artisan storage:link
publicディレクトリに移動して、シンボリックリンクを確認することができます。
cd /var/www/html/public
ls -la
上記コマンドを打って、以下のような感じでシンボリックリンクが作成されていればOKです。
storage -> /var/www/html/storage/app/public
ちなみに、これはDockerコンテナ上で実行しているので/var/www/htmlがルートディレクトリになっています。
普通にローカル上で、シンボリックリンクを貼ったら
「storage -> /User/あなたの名前/プロジェクト名/storage/app/public」とかになると思います。
php artisan:storage linkできない場合の対象方法
たまに、php artisan storage:linkコマンドを叩いてもエラーが出る時があります。
そのときは以下のようなエラー文が出ることがほとんどです。
Could not open input file: artisan:storage
こちらの解決方法を紹介します。
✔ 今いるディレクトリを確認
まずは、今いるディレクトリを確認してください。
プロジェクトのルートディレクトリにいないと失敗します。
「pwd」とターミナルで叩くと自分の今いるディレクトリが確認できます。
//例
pwd → /user/download //ダウンロードディレクトリにいるので失敗します
pwd → /user/project //対象プロジェクトにいるので失敗します
✔ storageディレクトリの所有権を確認
正しいディレクトリにいるのに、Could not open input file: artisan:storageが出る...という方は、storageディレクトリの所有権を確認してもいいかもです。
chown -R root:root storage
上記コマンドで、所有権をrootにできます。
それから、もう一度「php artisan storage:link」を実行してみてください。
自分はそれでうまくいきました
(ちなみに多分です...。直後はうまくいかなかったのですが、2分後とかにうまくいきました...。)
読み込みを確認しましょう
うまくシンボリックリンクを貼ることができたら、assetでstorage下のファイルを読み込んでいきましょう。
以下のコードでうまく表示されれば成功です。
<img src="{{ asset("storage/logo.png") }}" >
storage下では「storage/app/public/logo.png」になっていますが、読み込むのはpublic下にリンクされている「storage/logo.png」ってことですね。
ちなみに、これローカルストレージなんで、dockerコンテナ上でシンボリックリンク貼ってもローカルでstorage/logo.pngを見ることはできません....。
vsコードの場合ワークスペースとか操作すればコンテナ上のローカルストレージも確認できそうですね。
昔vagrantの環境をvscodeで見れるようにしたので多分いけるはず。
調べてみたら、Remote Containerという便利な拡張機能がありました。
これを使えばOKですね。
Laravel8でロゴ画像を設定する方法
さきほどの、画像読み込みの話を踏まえて、ロゴ画像を設定していきましょう。
public下に置く
まずは、ロゴに使いたい画像(logo.pngとかを)storage下に置きます。
「storage/app/public/logo.png」となるように置いてください。
そしたら、public側からstorage下の画像を参照できるように、シンボリックリンクを貼ります。
以下のコマンドを実行してください。
php artisan:storage link
うまくいくと、「public/storage」というgitで管理されないディレクトリができます。
その中に、さきほど置いたlogo.pngが入っているはずです。
らだし、こちらはgitでは管理されません。
ロゴ画像の場合gitでも管理してあげたいので、新規に「public/images」を作って、そこにlogo.pngを置いてあげましょう。
以下のようになっていればOKです。
既存のロゴを変更してみる
既存のロゴ画像を変更してみて、使用されているか確認してみましょう。
以下のコードで表示できればOKです。
<img src="{{ asset("images/logo.png") }}" >
もちろん、gitで管理しなくてもいい場合は以下のコードでもOKです。
<img src="{{ asset("storage/logo.png") }}" >
自分の場合は、一応gitにも残しておきたいので、imagesフォルダは作成しつつ、実際のコードではstorage下のものを読み込むようにしました。
今回は以上です。
参考になれば幸いです。