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 - 无法在控制器构造函数中获取会话的主要内容,如果未能解决你的问题,请参考以下文章
试图在laravel会话foreach中获取非对象的属性“id”