Laravel控制器构造方法中如何调用中间件闭包内的$selected_country_id变量
核心原因
Laravel的控制器构造方法执行时机早于中间件的执行时机,你在构造方法中定义的中间件闭包,会在构造方法运行完成后、控制器业务方法执行前才会被调用,所以构造方法运行时闭包里的$selected_country_id还没有被定义,自然无法直接读取。
方案1:在控制器业务方法中使用该变量
如果你的使用场景是在控制器的普通业务方法(非构造方法)中读取该值,可以通过控制器类属性传递:
class BaseController extends Controller { // 声明公共属性用于存储国家ID public $selected_country_id; public function __construct() { $this->middleware(function ($request, $next) { $this->selected_country_id = session()->get('browse_country_id') ?? 4; return $next($request); }); } // 示例业务方法 public function demo() { // 这里可以正常读取到属性值 dd($this->selected_country_id); } }
方案2:需要在中间件执行阶段运行构造内的逻辑
如果你原本就是想要在构造方法里拿到该值做初始化操作,可以直接把对应的逻辑放到中间件闭包内部执行:
class BaseController extends Controller { public function __construct() { $this->middleware(function ($request, $next) { $selected_country_id = session()->get('browse_country_id') ?? 4; // 直接在这里执行你原本要在构造方法里做的操作 dd($selected_country_id); return $next($request); }); } }
注意:不要尝试在构造方法中直接读取
session()获取值,Laravel的Session初始化是在web中间件组的StartSession中间件中完成的,该中间件执行时机晚于控制器构造方法,构造阶段直接读session永远只会拿到默认值4。
方案3:全局多处使用可存入请求实例
如果该值需要在控制器、视图、其他后置中间件等多个位置调用,可以将值挂载到请求实例上:
$this->middleware(function ($request, $next) { $request->merge(['selected_country_id' => session()->get('browse_country_id') ?? 4]); // 后续所有位置都可以通过 $request->selected_country_id 读取该值 return $next($request); });
内容的提问来源于stack exchange,提问作者Mokhtar Ghaleb
相关产品推荐
相关产品推荐

