You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 05:36:02