【问题标题】:laravel - Can't get session in controller constructorlaravel - 无法在控制器构造函数中获取会话
【发布时间】:2017-05-23 09:44:58
【问题描述】:

在新的 laravel 中,我无法在构造函数中获取会话。为什么?

public function __construct()
{
    dd(Session::all()); //this is empty array
}

然后在下面

public function index()
{
    dd(Session::all()); //here works
}

我记得在旧的 laravel 中没有这个问题。有什么变化吗?

【问题讨论】:

  • 因为你不应该,真的。
  • 为什么不呢,你可以从会话中进行一些身份验证检查

标签: php laravel session constructor


【解决方案1】:

Laravel 5.3 sessions related functionality will not work in the a controller constructor,所以你应该把所有与会话相关的逻辑移到方法中。

【讨论】:

  • 这也适用于 Laravel 5.4。
  • laravel 5.6 - 相同
  • 是否有某种回调可以让我检查内容,它会在构造函数之后但在实际函数之前调用?
【解决方案2】:

默认情况下你不能在 Laravel 5.3 中做到这一点。但是,当您编辑 Kernel.php 并将 protected $middleware = []; 更改为以下内容时,它会起作用。

protected $middleware = [
    \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
    \Illuminate\Session\Middleware\StartSession::class,
    \Illuminate\View\Middleware\ShareErrorsFromSession::class,
];

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,

        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
    'api' => [
        'throttle:60,1',
        'bindings',
    ],
];

希望这行得通!

【讨论】:

  • 您确定这不会破坏web.php 内部路由的会话功能吗?你测试了吗?
  • @AlexeyMezenin 和我的 Laravel 项目一切正常,我从 web 数组中移动了最后两个。
  • @gogagubi 很好,如果这可行,您可以通过接受此答案向其他用户展示这可以正常工作!
  • 我通过添加这些行遇到了另一个问题。控制器和视图之间的会话不起作用。
  • 但我找到了解决方案。我已经在 $middlewareGroups 数组中注释了相同的两行,现在它可以工作了。
【解决方案3】:

对于其他答案,没有开箱即用的解决方案。 但是你仍然可以在构造函数中使用中间件访问它。

所以这是另一个 hack

public function __construct(){
    //No session access from constructor work arround
    $this->middleware(function ($request, $next){
        $user_id = session('user_id');
        return $next($request);
    });

}

【讨论】:

  • 您能解释一下这是如何/为什么起作用的吗?我自己想不通
  • 此解决方案不起作用..请建议您是如何做到的。
【解决方案4】:
 *This one solved mine problem to use session in constructor* 
   $this->middleware(function ($request, $next) {
        if (!session('records_per_page')) {
            session(['records_per_page' => 20]);
        }

        // update rows per page
        if (!empty(\Request::get('records_per_page')) && in_array(\Request::get('records_per_page'), [20, 50, 80, 100])) {
            session(['records_per_page' => \Request::get('records_per_page')]);
        }
        return $next($request);
    });

【讨论】:

    【解决方案5】:

    Laravel 5.7 解决方案

    public function __construct()
    {
    
    $this->middleware(function ($request, $next) {
    // fetch session and use it in entire class with constructor
    $this->cart_info = session()->get('custom_cart_information');
    
    return $next($request);
    });
    
    }
    

    如果您想将构造函数用于任何其他功能或查询或数据,请在 $this->middleware 函数中完成所有工作,而不是在此之外。如果您这样做,它将无法在整个班级的所有功能中发挥作用。

    【讨论】:

    • @Miron 我还没有用 Laravel 7.0 测试它,但很高兴听到它在 Laravel 7.0 更高版本中也能工作。谢谢亲爱的:)
    • 谢谢!这在 Laravel 7 中为我做到了。搜索了一个小时,然后就很容易了……
    • 我用 Laravel 8 试过这个,我可以确认它正在工作
    【解决方案6】:

    我在使用中间件的构造中使用了Session,你可以试试,会有所帮助

    public function __construct()
    {
        $this->middleware('PM');
    
        $this->middleware(function ($request, $next){
            $school_id = Session::get('school_id');
    
    
            return $next($request);
        });
    }
    

    【讨论】:

    • 请解释你的答案。
    • 我在使用中间件的构造中使用了Session,你可以试试,会有帮助
    【解决方案7】:

    从 Laravel 6.18.1 开始,将这些添加到 kernel.php 中的 $middleware 数组

    \Illuminate\Session\Middleware\StartSession::class,
    \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    

    它应该可以工作。

    【讨论】:

      【解决方案8】:

      如果现在有人遇到这个问题,我建议不要在控制器构造函数中访问会话值,而是创建一个中间件并将其放在 App\Http\Kernel 的 Web 中间件部分。

      这是因为会话不是传递给控制器​​构造函数的请求的一部分。然后在每个控制器中进行任何会话值检查或操作,创建中间件会更安全。

      这是作为进入路由的 HTTP 请求的一部分访问会话值的地方。

      `/**
       * The application's route middleware groups.
       *
       * @var array
       */
      protected $middlewareGroups = [
          'web' => [
              ...,
              ...,
              ...,
              ...,
              ...,
              \Illuminate\Session\Middleware\StartSession::class,
              \App\Http\Middleware\MySpecialMiddleWareToAccessSessionVariables::class
          ],
      
          'api' => [
              'throttle:60,1',
              'bindings',
          ],
      ];`
      

      这是因为\Illuminate\Session\Middleware\StartSession 在到达您的路线之前已经开始了会话

      【讨论】:

        【解决方案9】:

        在app\Http\kernel.php的$middleware数组底部添加这两个

        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        

        这对我来说很好。

        【讨论】:

          猜你喜欢
          • 2021-04-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多