laravel - 无法在控制器构造函数中获取会话

Posted

技术标签:

【中文标题】laravel - 无法在控制器构造函数中获取会话【英文标题】:laravel - Can't get session in controller constructor 【发布时间】: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 中没有这个问题。有什么变化吗?

【问题讨论】:

因为你不应该,真的。 为什么不呢,你可以从会话中进行一些身份验证检查 【参考方案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,

这对我来说很好。

【讨论】:

以上是关于laravel - 无法在控制器构造函数中获取会话的主要内容,如果未能解决你的问题,请参考以下文章

PHP Laravel:如何设置或获取会话数据?

我如何访问 laravel 上的会话?

试图在laravel会话foreach中获取非对象的属性“id”

在 laravel 中会话超时或过期后触发函数

Laravel 请求:直接在控制器构造函数中注入请求是正确的吗?

在同一控制器中以其他方法访问会话数据在 laravel 中不起作用