@iwantit

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

【Laravel 7】Controllerの__constructでユーザ情報を渡してDBからデータ取得したい

【やりたい事】
LaravelのControllerの__constructでユーザ情報を渡してDBからデータ取得したい。

【現状】
上記の方法が分からないので、indexメソッドでユーザ情報を渡してDBからデータ取得している。
index以外にもメソッドがあり、それぞれのメソッドから個別に処理を書いてDBからデータ取得しています。

どのように書けばいいのか行き詰まりどなたか教えて頂ければと思います。
宜しくお願い致します。

【開発環境】
Windows 10 HOME
Laravel Framework 7.2
PHP 7.4.8
MySQL

qiita.php
class Tbl_MoneyController extends Controller
{
    private $user;

    public function __construct()
    {
        //ログイン認証
        $this->middleware('auth');


        $this->middleware(function ($request, $next) {
            // ログイン情報
            $this->user = \Auth::user();
        //  print_r($this->user); ※1
            return $next($request);
        });

        1のログイン情報を下記に渡したい

        //こっちで「ログイン情報」を渡してDBからデータを取得したい
    $money_arr = DB::table('tbl_money')
    ->where('name', xxxxx)
    ->orderBy('buy_date', 'desc')
    ->get();

    }

    /***********************************/
    //index画面
    /***********************************/

    public function index()
    {
        $user = $this->user;
    //  print_r($user->name);

        $money_arr = DB::table('tbl_money')
        ->where('name', $user->name)
        ->orderBy('buy_date', 'desc')
        ->get();
'''
0 likes

2Answer

middlewareで登録した関数が実行されるのは、コンストラクタを抜けてからです。
なのでコンストラクタで$this->userは使えないです。

            $this->user = \Auth::user();
            $this->money_arr = DB::table('tbl_money')-> ...
            return $next($request);

のようにAuth::user()の下に書いてしまえばできそうですが、コンストラクタは共通処理を書く場所ではなく初期化処理を書く場所であり、middlewareは様々な画面の横断的処理を書く場所なので、ここで画面の具体的な処理はやるべきじゃないです。

【現状】
上記の方法が分からないので、indexメソッドでユーザ情報を渡してDBからデータ取得している。
index以外にもメソッドがあり、それぞれのメソッドから個別に処理を書いてDBからデータ取得しています。

こちらの最初のやり方で特に問題なさそうです。DB処理があちこちにあるということなら

    // ...

    private function getMoney()
    {
        return DB::table('tbl_money')
            ->where('name', $this->user->name)
            ->orderBy('buy_date', 'desc')
            ->get();
    }

    public function index()
    {
        $money_arr = $this->getMoney();
        // ...
    }

    public function index2()
    {
        $money_arr = $this->getMoney();
        // ...
    }

こうでしょうか。

※ Laravel は使っていないので独自の流儀は分かりません。

1Like

Comments

  1. @iwantit

    Questioner

    @nishimura 様

    ご回答ありがとうございます。
    middlewareとコンストラクタの説明非常によくわかりました。

    書いて頂いたメソッドもまさにイメージ通りで正常に動作しました。
    念のために確認したいのですが getMoney を「private」にしたのはやはりDBにアクセスする上で「private」の方がセキュリティ的にも安全だからという事でしょうか?
  2. privateにするのはセキュリティのためではなく、変更しやすくするためです。
    基本的に他のクラスから使わないものは全てprivateにします。
    publicにすると、何か変更するたびに他のクラスから利用されていないかどうか確認する必要が出てきます。
    あと、publicは1画面1メソッドとしてフレームワークから呼び出される処理、privateは内部で呼び出す処理ということがぱっと見て分かるので単純に見やすいです。
  3. @iwantit

    Questioner

    なるほど。非常に勉強になりました。
    詳細な解説ありがとうございました。

こんな感じでしょうか

<?php
class Tbl_MoneyController extends Controller
{
	private $user;
	private $buy_history;

	public function __construct()
	{
		//ログイン認証
		$this->middleware('auth');


		$this->middleware(function ($request, $next) {
			// ログイン情報
			$this->user = \Auth::user();
			return $next($request);
		});

		$this->buy_history();

	}

	private function buy_history()
	{
		$this->buy_history = DB::table('tbl_money')
			->where('name', $this->user->name)
			->orderBy('buy_date', 'desc')
			->get();
	}
}
0Like

Comments

  1. @iwantit

    Questioner

    $buy_history様 ご回答ありがとうございます。

    上記のコードを実行したら下記のエラーメッセージがでました。
    Trying to get property 'name' of non-object

    またできれば__construct内で下記を記載して実行まで行いたいのですが、
    それは難しいのでしょうか?

    $money_arr = DB::table('tbl_money')
    ->where('name', xxxxx)
    ->orderBy('buy_date', 'desc')
    ->get();


    宜しくお願い致します。

Your answer might help someone💌