質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.80%

Laravel 6.*でimageが表示できない

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 253

score 7

初学者です。Laravel(6.20.16) uiを使って、ユーザーからinputで取得した画像を投稿する機能を実装しようと考えています。取得した画像はRequestでバリデーションした後、ControllerでDBに保存され、bladeで表示されるようにする流れを考えています。

投稿画面create.blade.php

<div class="col-md-6 mb-4">
<form method="POST" enctype="multipart/form-data"action="{{ route('articles.store') }}">
  @csrf
          <div class="file-field">
           <div class="d-flex justify-content-center">
              <div class="btn btn-mdb-color aqua-gradient btn-rounded float-left">
                <span>アルバムから選択</span>
                <input type="file" name="image">//画像取得
              </div>
            </div>
          </div>
      </div>
<button type="submit" class="btn  btn-block">投稿する</button>
</form>

取得した画像をLetterRequestでバリデーション

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class LetterRequest extends FormRequest
{
    //略
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'image' => 'file|image|max:10000|present|nullable|sometimes',            
        ];
    }

//以下略


バリデーションした画像を、LetterControllerでDBに格納。
まずpublicディレクトリに保存し、それからDBに入れるような流れです。
(画像はファイル名とパスを取得して保存するようにしました。)

if(isset($request->image)) //画像が存在したら
      {
        $request->image = $request->file('image')->store('public/images');
        $request->image = str_replace('public/images/', '', $image);//publicディレクトリに格納
        $letter->file_name= $request->image->getClientOriginalName();//ファイル名と
        $letter->file_path = $request->image->getRealPath();//パスを取得し、DBに保存
        then(move($request->file_path,'public/images'));
      } 
      else{
      } ;
      $letter->save();
   return redirect()->route('articles.index');
//以下略

そして、DBからデータを取り出して表示します

<div class="container">
@foreach ($letters as $letter)
    <div class="card">
      <div class="bg-image hover-overlay ripple"  data-mdb-ripple-color="light">
        <img
          class="img-fluid" src='{{$letter->file_path}})'
        />
      </div>
//以下省略

しかし、い表示してみると、画像はうまく表示されず、表示されなかったとき用のいつものテンプレマークが表示されるだけです。DBをみると、投稿画面から取得した画像のファイル名、パス共に正しく格納されていました。

また、実装途中でシンボリックリンクを行うことでpublicにstorageファイルが生成され、画像がそこに保存されると知ったので、CLIでphp artisan storage:linkを行いました。しかし、エディタ上にはstorageファイルは見当たりません。エクスプローラーで確認するとstorageファイルがpublicディレクトリの中に生成されていたので、直接エディタの中にコピペしようと思いましたが、エラーが表示されコピペできませんでした。
Error: EACCES: permission denied, stat Cドライブ~
ググってみると認証を緩和することが必要と書かれていたので、CLIで
 chmod -R 777 storage
を叩きましたが、効果なしでした。

どこかのコードを誤って記述している可能性が高いのかなと思うのですが、私のバカ頭ではどうしようもできませんでした。どなたかご教授頂けると幸いです。よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

アクションで、アップロードされたファイルの処理が少しおかしい気がしています。
以下のような感じにするのは不都合がありますか?

if(isset($request->image)) //画像が存在したら
{
    // アップロードファイルを storage/app/public/images/ ディレクトリへ保存
    $path = $request->file('image')->store('public/images');

    // ファイルの元の名前と保存先のパスを Letter へセット
    $letter->file_name= $request->file('image')->getClientOriginalName();
    $letter->file_path = $path;
}

// 中略

$letter->save(); // Letter を保存

参考: ファイルアップロード

Letterモデルでは、ファイルURLを取得できるようなアクセサを定義しておくと良いと思います。

use Illuminate\Support\Facades\Storage;

// 中略

    /**
     * ファイルURLを取得
     *
     * @return string
     */
    public function getFileUrlAttribute()
    {
        return Storage::url($this->file_path);
    }

参考:

Bladeで以下のように記述すると、上記のアクセサが呼び出され、ファイルURLを取得できます。

<img class="img-fluid" src="{{ $letter->file_url }}">

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

ご回答ありがとうございます!
どうやらDocker周りとの連携ミスのようです…提示していただいたコード、熟読させていただきます。
詳細なご教授ありがとうございます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.80%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る