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

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

ただいまの
回答率

87.77%

Laravelにて、POSTで送信した複数の画像をビューで表示させる方法

受付中

回答 1

投稿 編集

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

score 8

Laravelで知恵袋的なWebサービスを開発中です。
投稿フォームのビュー(create.blade.php)で、

<input type="file" name="image[]">

と、画像が複数送信された際に対応できるよう、nameの中のimageの末尾に[]を付けていますが、これは正しい考えでしょうか?

LecturesController ではこのように書いています。

public function store(Request $request) {

$this->validate($request, [
'category_name' => 'required',
'title' => 'required|max:100',
'content' => 'required',
]);

if($request->file('image')) {
$lecture = new Lecture;

$lecture->user_id = \Auth::id();
$lecture->category_name = $request->category_name;
$lecture->title  = $request->title;
$lecture->content = $request->content;

// リクエストされた image データ(View側の name)を $images に代入
$images = $request->file('image');

// foreach で $images に入った画像を $image として別個に取り出す
foreach ($images as $image) {

// UNIXタイムスタンプを取得したものと、ユーザーID、オリジナルの拡張子を取得したものとを繋ぎ、ファイル名として $filename に代入
$filename = time() . '_' . $lecture->user_id . '.' . $images->getClientOriginalExtension();

// storeAs の第1引数は storage からのパス、第2引数はファイル名、第3引数は利用するストレージ(local、public…など)
$path = $image->storeAs('', $filename, ['disk' => 'public']);

// パスを image カラムに代入
$lecture->image = $path;

// 最終的な状態を保存
$lecture->save();

}

else {
$request->user()->lectures()->create([
'category_name' => $request->category_name,
'title' => $request->title,
'content' => $request->content,
]);
}

return redirect('/');
}


また、画像を表示させたいビューの当該部分はこちらです。

show.blade.php

@if ($lecture)
@if ($lecture->image)
<figure class="show_post_thumbnail"><div class="new_area-img text-center"><img class="show_image" src="{{ asset('storage/'.$lecture->image) }}"></div></figure>
@else
<figure class="show_post_thumbnail"><div class="new_area-img text-center"><img src="../img/noimage.gif"></div></figure>
@endif


以上の内容で画像を付けて投稿すると、このようなエラーが出てきます。

Call to a member function getClientOriginalExtension() on array

ちなみに、imageの末尾に[]を付けず、コントローラーの中でforeach文も取り除くと、画像を投稿してもエラーは出ません。
もちろん、画像は1枚しか出てこないですが。

どなたか詳しい方いらっしゃいましたら、アドバイスいただけると幸いですm(_ _)m

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • m.ts10806

    2020/04/27 14:14

    コードは全て、ファイル毎にマークダウンのcode機能を利用してご提示ください。

    キャンセル

  • Keight

    2020/04/27 14:21

    すみません、書き方がよくないのかどうかわかりませんが、code機能(ブロック用)を使うとレイアウトが崩れてしまうようです・・・。
    書き方これで合っていますか?

    ```php
    ここにコードを書きました。
    ```

    キャンセル

  • m.ts10806

    2020/04/27 14:23

    合ってます。
    どのように崩れたいのか分からないですが、正しく囲えば幾つでもいけますよ

    キャンセル

  • Keight

    2020/04/27 14:34

    そうなんですね。
    その書き方でプレビューを確認すると、なぜか崩れてしまいます。
    こんな感じです。
    https://gyazo.com/b64edb38de4b3fe900305de91248009a

    キャンセル

回答 1

0

$filename = time() . '_' . $lecture->user_id . '.' . $images->getClientOriginalExtension();


の部分で $imagesを参照しているので$imagesではなく、foreachのvalue部分、$imageを参照するようにすれば解決するかと思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/04/27 14:49

    表示部分のロジックというのは、こちらになるでしょうか。

    public function show($id) {
     $lecture = Lecture::find($id);
     return view('lectures.show', [
     'lecture' => $lecture,
     ]);
    }

    showの引数が id となっているので、この中で「画像のデータを配列で渡す」という処理は行えないのでしょうか?
    ということは、別にテーブルを作り、レクチャー1に対して画像を多の関係にする必要があるわけですね。
    そういう発想はなかったので参考になります、ありがとうございますm(_ _)m

    キャンセル

  • 2020/04/27 14:54

    > showの引数が id となっているので、この中で「画像のデータを配列で渡す」という処理は行えないのでしょうか?
    たとえば、外部の別テーブルに LectureのIDを外部キーとして画像を列挙するようにして、 where('lecture id', $id) のようにすれば配列で取ることもできるかと思います。
    ただここまでくると、Lectureに対して画像データをどのようにもたせたいかのデータの関係定義の話になってしまうので、この質問の本筋からはずれてしまうかと思います。
    とりあえず画像のアップロードを1枚までのまま、foreach を残したいというのであれば、アップロード側は上記の変更で修正ができるかと思います。

    キャンセル

  • 2020/04/27 15:07

    現状、Laravelの勉強を始めたばかりなのでほとんど引き出しがないのですが、一度 1対多 の関係について学んでみたいと思います。
    その上で、画像を複数送信できる仕様とするか、それとも1つの画像しか投稿できないようにするかの判断をしたいと思います。
    いろいろとありがとうございました。

    キャンセル

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

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

関連した質問

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