🐕

【Laravel】Model内で変数をグローバル宣言したい

2022/12/17に公開

Model内にクエリビルダを使ってSQLを記述しています。
クロージャ(functionの中のfunction)でグローバル変数を使用したいのですが、null が返ってきてしまい、数時間ハマったため備忘録として残します。

目次

  • 結論
  • useとは

結論

下記の通り実装することで動作確認できました。

public function check_notify_user($auth_user_id) {
  $query = DB::table('notifications as n')
      ->leftJoin('notification_user as nu', function ($join) use($auth_user_id){
          $join->on('n.id', "=", 'nu.notification_id')
          ->where('nu.user_id', "=", $auth_user_id);
      })
      ->where('nu.user_id', null)
      ->get();

  return $query;
}

重要箇所はleftJoinの中にあるuse($auth_user_id) です。
check_notify_userの引数にControllerで定義した$auth_user_idを使っています。use($auth_user_id) を使用することで、クロージャの外で定義した変数を使用できるようにしています。

useとは

今回のエラーは全てドキュメントに答えが書いてありました。
function() use(変数名)は、PHPで定められた記法。

クロージャは、変数を親のスコープから引き継ぐことができます。 引き継ぐ変数は、use で渡さなければなりません。 PHP 7.1 以降は、引き継ぐ値に スーパーグローバルや $this、およびパラメータと同じ名前の変数を含めてはいけません。 戻り値の型は、useに置かなければいけません。

参考:無名関数
クロージャーは親のスコープを引き継ぐことが可能ですが、親スコープの関数を使用する際には必ずuse で変数を継承しなければなりません。
PHPの知識が不足していると、LaravelとPHPのどちらが原因なのか判断できないので基礎固めは重要、ということを改めて実感した今日この頃です。

参考:【Laravel】function () use ($変数名)とは何か?意味や使い方を実例で解説|無名関数の外の変数を使う方法とエラーの対処法:ErrorException (E_NOTICE) Undefined variable
参考:変数のスコープ

Discussion