こんにちは!
今回はタイトルの通り、フォームからアップロードした画像を表示する方法についてお伝えしていきたいと思います。
開発環境
・Laradock(docker環境)
・Laravel Framework 7.11.0
・MySQL
やりたいこと
フォームから
画像をアップロード&サーバーに保存
その画像を商品一覧ページに表示したい
手順
この記事では画像アップロード後の処理をメインに書いていきますので、ご了承ください。
誤り等を発見されたら、問い合わせフォームからご連絡いただけると幸いです。
(前提)
・"app"というLaravelプロジェクト名で作成(ややこしくてすみません...)
・こちらのサイトやドキュメントを参考にしながら、ECサイトの管理画面とフロントページを作成
・storeAs
メソッドを用いて、フォームからアップロードした画像を保存
//コントローラー内の画像を保存する処理
$filename = $request->file('image')->storeAs($up_dir, $upload_name, 'public');
app/storageに保存されていることを確認
※purblic内ではない事に注意
ここから本題
今のままだと、htmlで img src = "./storage./app/public/image/image.png"
のように記述しても読み込まれません。
理由としてはpublic内にある画像しか読み込まれないからだそうです。
つまり、publicの外にあるstorageにあるものは読み込ません。
(相対パスで../../
のようにしてもダメでした...)
対処法は「シンボリックリンクを設定し、publicから参照するできるようにする」です。
//dockerコンテナ内に移動(※ここ忘れがち)
$cd laradock
$docker-compose exec workspace bash
//シンボリックリンク設定
root@e99ca2d4057e:/var/www/app# php artisan storage:link
The [/var/www/app/public/storage] link has been connected to [/var/www/app/storage/app/public].
The links have been created.
//設定できている事を確認
root@e99ca2d4057e:/var/www/app/public# ls -la
total 20
・・・
lrwxrwxrwx 1 root root 31 May 18 13:58 storage -> /var/www/app/storage/app/public
・・・
実際にファイルが存在することを確認するため、 /var/www/app/public/storage/image
に移動します。
root@e99ca2d4057e:/var/www/app/public/storage/image# ls
1_image.jpg
2_image.png
public内から参照できることを確認しました。
あとは実際にhtmlに記述して、表示されることを確認します。
<img src="/storage/image/image.png" alt="" >
うまく表示することができました〜
詰まったところ
コンテナの外(ローカル内)でシンボリックリンクで設定したら、リンクは設定できたけど、画像が読み込めなかった
//ローカルフォルダでシンボリックリンク
$ php artisan storage:link
The [/Users/Developer/03_study/php/test/app/public/storage] link has been connected to [/Users/Developer/03_study/php/test/app/storage/app/public].
The links have been created.
$ cd public/
$ ls -la
・・・
lrwxr-xr-x 1 kenta staff 65 5 18 23:03 storage -> /Users/Developer/03_study/php/test/app/storage/app/public
・・・
原因
docker環境(Laradock)で構築している場合はdockerコンテナ内でシンボリックリンクを設定する必要があった。
対策
上に書いたように、docker-compose exec workspace bash
でdockerコンテナ内に入ってから、シンボリックリンクを設定する
->ls -la
の結果、storage -> /var/www/
のように表示されていたらOKです。
コンテナの理解が甘いなと反省。。。
余談
コンテナ内でシンボリックリンクした後、ローカルでもシンボリックリンクしようとするとエラーなりました。
//コンテナ内でシンボリックリンク
root@e99ca2d4057e:/var/www/app# php artisan storage:link
The [/var/www/app/public/storage] link has been connected to [/var/www/app/storage/app/public].
The links have been created.
//同様にローカル内でシンボリックリンク
$ cd app
$ php artisan storage:link
ErrorException
symlink(): No such file or directory
at vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php:263
259| */
260| public function link($target, $link)
261| {
262| if (! windows_os()) {
> 263| return symlink($target, $link);
264| }
265|
266| $mode = $this->isDirectory($target) ? 'J' : 'H';
267|
+16 vendor frames
17 artisan:37
Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
以上になります〜