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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

3回答

3705閲覧

【Laravel】return で複数の変数を返せない。

gyu

総合スコア3

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2020/11/06 06:08

問題

複数の変数をreturnで返せない。

return [$posts, $lgtm_min, $lgtm_max];

エラー

ErrorException compact(): Undefined variable: posts

どこか、returnの記述方法を間違えているようなのですが、それがわかりません。

試した例

php

1return $posts, $lgtm_min, $lgtm_max; 2return [$posts, $lgtm_min, $lgtm_max]; 3return array($posts, $lgtm_min, $lgtm_max); 4return compact($posts, $lgtm_min, $lgtm_max);

詳細

fat controller解消のために、PostController.phpの絞り込み検索を分離させた。
(DetailedSearch.phpに処理を移行)

作成したDetailedSearch.phpは下記になる。
app/Services/DetailedSearch.php

DetailedSearch

1<?php 2 3namespace App\Services; 4 5use Illuminate\Support\Facades\DB; 6 7class DetailedSearch 8{ 9 public static function DetailedSearch($query, $lgtm_min, $lgtm_max, $order) 10 { 11 //LGTM sum search 12 if ($lgtm_min !== null) { 13 $query->having('likes_count', '>=', $lgtm_min); 14 } 15 if ($lgtm_max !== null) { 16 $query->having('likes_count', '<=', $lgtm_max); 17 } 18 19 if ($order == 'new') { 20 $posts = $query->orderBy('posts.created_at', 'desc')->paginate(20); 21 } else { 22 $posts = $query->orderBy('likes_count', 'desc')->paginate(20); 23 } 24 25 26 return [$posts, $lgtm_min, $lgtm_max]; 27 } 28}

このDetailedSearchをPostController.phpで利用し、結果の値を取得する。

DetailedSearch::DetailedSearch($query, $lgtm_min, $lgtm_max);が実際に利用した箇所です。

PostController

1<?php 2 3namespace App\Http\Controllers; 4 5use App\Models\post; 6use App\Models\tag; 7use Illuminate\Http\Request; 8use Illuminate\Support\Facades\Auth; 9use Illuminate\Support\Facades\DB; 10use App\Services\DetailedSearch; 11 12class PostController extends Controller 13{ 14 15public function my_posts(Request $request) 16 { 17 // values 18 $lgtm_min = $request->input('lgtm-min'); 19 $lgtm_max = $request->input('lgtm-max'); 20 21 // query 22 $query = Post::where("posts.user_id", "=", Auth::user()->id)->withCount('likes'); 23 24 //絞り込み処理 25 DetailedSearch::DetailedSearch($query, $lgtm_min, $lgtm_max); 26 27     //エラー:compact(): Undefined variable: posts 28 return view('posts.my_posts', compact('posts', 'all_posts_count', 'keyword', 'order', 'lgtm_min', 'lgtm_max')); 29 }

これで$postsを取得できると思ったが、結果はエラーが表示された。
イメージ説明

下記が実際のエラーメッセージ

ErrorException compact(): Undefined variable: posts

問題の絞り込み

$postsを定義できていないエラーのため、DetailedSearch.phpが失敗していることがわかる。

そこで、dd($posts);を記述し、$postsが定義しているか?値を取得できているか確認した。

DetailedSearch

1<?php 2 3namespace App\Services; 4 5use Illuminate\Support\Facades\DB; 6 7class DetailedSearch 8{ 9 public static function DetailedSearch($query, $lgtm_min, $lgtm_max, $order) 10 { 11 //LGTM sum search 12 if ($lgtm_min !== null) { 13 $query->having('likes_count', '>=', $lgtm_min); 14 } 15 if ($lgtm_max !== null) { 16 $query->having('likes_count', '<=', $lgtm_max); 17 } 18 19 if ($order == 'new') { 20 $posts = $query->orderBy('posts.created_at', 'desc')->paginate(20); 21 } else { 22 $posts = $query->orderBy('likes_count', 'desc')->paginate(20); 23 } 24 25 //ddを追加 26 27 dd($posts); 28 return [$posts, $lgtm_min, $lgtm_max]; 29 } 30}

dd($posts)の結果、配列を取得できていることがわかる。
イメージ説明

このことから、DetailedSearch.phpのreturn直前まで値を取得できているとわかった。

今度は,PostController.php側でdd($posts)を追加

PostController

1DetailedSearch::DetailedSearch($query, $lgtm_min, $lgtm_max, $order); 2 3// 追加 4dd($posts); 5return view('posts.my_posts', compact('posts', 'lgtm_min', 'lgtm_max'));

するとdd($posts)の箇所でエラーが表示された。
イメージ説明

ErrorException Undefined variable: posts

これらのことから、

DetailedSearch.phpのreturn [$posts, $lgtm_min, $lgtm_max];の記述に問題があるとわかった。

そこで、いくつかreturnについての記事を参考にしましたが、解決に至ってません。
https://www.php.net/manual/ja/language.references.return.php
https://qiita.com/tatsuo-iriyama/items/b0c2dda4426e42d8bc78

お忙しいと思いますが、ご教授のほどよろしくお願いします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

返り値を受け取ってないだけ。

list($posts, $lgtm_min, $lgtm_max) = DetailedSearch::DetailedSearch($query, $lgtm_min, $lgtm_max);

それよりもDetailedSearch()をstaticで書いてるほうが後で困る。
Laravelを知らない人が一番間違える所。

DBの処理するような部分はstaticメソッドで書かない。

サービスクラスに分離した時はこう使う。
(そもそも$query = Post::where…もDetailedSearch内に入れたほうがいいけど)

public function my_posts(Request $request, DetailedSearch $search) { list($posts, $lgtm_min, $lgtm_max) = $search->DetailedSearch($query, $lgtm_min, $lgtm_max); }

これの何が便利なのかはテストを書かないと理解できない。
DBを使う箇所を全部モックして無視できる。
Laravelのほとんどの機能はテストのためと言っても過言ではないのでとにかくテストを書かないとLaravelは理解できない。

投稿2020/11/06 06:42

kawax

総合スコア10377

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gyu

2020/11/06 08:19

無事できました!恥ずかしいほどに基本的な内容でした ありがとうございました!!
guest

0

イメージ説明

赤枠の中に $posts がないのでエラーになってます。

投稿2020/11/06 06:18

phper.k

総合スコア3923

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gyu

2020/11/06 08:20

わかりやすくありがとうございます!
guest

0

DetailedSearch::DetailedSearch($query, $lgtm_min, $lgtm_max, $order);を呼んだのに、返り値を受け取っていないので、ただ捨てられています。

投稿2020/11/06 06:21

maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2020/11/06 06:21

DetailedSearch::DetailedSearchの中の問題ではなく、「呼ぶ側」の問題です。
gyu

2020/11/06 08:20

本当ですね! いやーお恥ずかしい ありがとうございました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問