Laravel 5:会话没有按应有的方式工作
Posted
技术标签:
【中文标题】Laravel 5:会话没有按应有的方式工作【英文标题】:Laravel 5: Sessions not working the way they should 【发布时间】:2016-02-26 23:56:08 【问题描述】:在我使用的每个控制器和 routes.php 之上:
use Illuminate\Support\Facades\Session;
在 routes.php 中,我使用以下方式设置会话:
Session::put('key', 'value');
在控制器中我想调用key
的会话值:
echo Session::get('key');
但是一旦我在 routes.php 中为key
设置了一个新值并在控制器中调用它,我仍然会得到第一个值而不是新值。如果我在设置后在 routes.php 中使用Session::all()
回显会话,我会看到新值,但在控制器中它会翻转回第一个值。在设置新值之前,我什至尝试在 routes.php 中使用 below,但没有成功。
Session::forget('key');
我是不是忘记了什么?
使用常规 PHP $_SESSION
我的 routes.php 看起来像这样:
$slug = $_SERVER['REQUEST_URI'];
$slug = explode('/', $slug[0]);
if(in_array($slug[1], Language::all()->lists('iso')))
$_SESSION['language'] = $slug[1];
if(!$slug[2])
$_SESSION['slug'] = 'home';
Route::any('/slug', ['as' => 'pages.page', 'uses' => 'PagesController@page']);
else
if($slug[2] != 'dashboard' && $slug[2] != 'migrate' && $slug[2] != 'form-send')
if (in_array($slug[2], ElementValue::where('element_field_id', 2)->lists('value_char')) && !isset($slug[3]))
$_SESSION['slug'] = $slug[2];
Route::any('/slug', ['as' => 'pages.page', 'uses' => 'PagesController@page']);
else
$_SESSION['slug'] = 'home';
Route::any('/slug', ['as' => 'pages.page', 'uses' => 'PagesController@page']);
【问题讨论】:
为什么要在 route.php 中设置会话,然后在控制器中使用该值?如果您使用控制器,则应在控制器或中间件中设置任何会话值。 也发布您的 routes.php 代码 刚刚在我的问题中添加了路线部分 嗯看起来很'un-laravel'。我建议通过文档并做一些教程。 Routes.php 在 laravel 中不应该是这样的。许多更好的方法来做到这一点,比如在使用 Request 类的中间件中 【参考方案1】:routes.php
中的哪里你在设置会话值?听起来你正在做这样的事情:
Session::put('key', 'value');
Route::get('my-route', 'MyController@doSomething');
然后这样做:
class MyController
public function doSomething()
Session::get('key');
正确吗?如果是这样,请继续阅读...
我不是 Laravel 请求生命周期方面的专家(更多信息,see the documentation),但我并不惊讶这不起作用。我的想法是这样的:routes.php
文件在生命周期的早期被加载和执行——可能是第一个——因为它告诉应用程序接下来要执行什么代码(即,当收到特定请求时做什么)。当我说“生命周期的早期”时,我的意思是早期 - 就像在会话初始化之前一样。我相信 Session::put
调用只是被忽略了,因为在您设置值时,会话不存在。
您可能希望通过更多详细信息来扩展您的问题,了解您想要完成的工作 - 必须有更好的方法来做到这一点。
EDIT - 响应下面的 cmets...
我不说你应该触摸$_SESSION
superglobal - 这是一个坏主意,因为我什至不确定 Laravel 使用原生 PHP 会话工具和你无法保证你所做的任何事情将来都会继续工作。
不清楚您要做什么,但对我来说,这听起来像是一个不属于会话的值。
通过将Session::put
放在routes.php
文件中,听起来您有一些重要的值,应该为每个会话和每个请求设置
如果是这样,并且它是一个静态值,那么它就不是一个会话值,它是一个配置值。
如果相反,它是一个动态值和/或它会根据与会话关联的用户而变化,那么您可以在以下几个位置之一进行设置:
如果您使用基于控制器的路由,您可以在控制器构造函数中设置它,尽管我不建议这样做,因为您可能需要多次这样做控制器,导致代码重复
如果您在路线中使用闭包,请将其设置在那里。例如
Route::get('some/route', function ()
Session::put('key', 'value');
// this works, because the closure isn't executed until after
// the application is initialized
);
你也可以在middleware进行操作
或service provider(虽然我不确定在执行服务提供者时会话是否可用)。
最好的选择可能是中间件 - 这将允许您在代码中的一个位置设置(或计算)会话值,并将其与特定路由相关联,如果您不需要它用于所有路由。
【讨论】:
所以你实际上是说如果我想在路由中设置会话,php 我应该使用常规 PHP$_SESSION
?
或在此处提到的配置中:***.com/questions/28417796/…
@AlvinBakker:laravel 没有使用普通的 PHP $_SESSION
,所以你不能使用它
好吧,它可以工作,只是想以 laravel 的方式使用它。查看我改编的问题
@Kryten 是对的,我刚才为此创建了一个问题,但我相信这是预期的行为:github.com/laravel/framework/issues/8244【参考方案2】:
不要在 laravel 中使用 $_SESSION
。使用 laravel Session
类。见以下帖子How to access the globals $_SESSION and $_COOKIE from a laravel app?
另外,你所有的if
逻辑都不应该存在于 routes.php 中。您应该将其添加到中间件以过滤您的路由。
另外,你真的让自己很难做到这一点。 Laravel 在方便的帮助类中提供了你需要的大部分内容,例如Request::url()
、Request::getHost()
、Request::getLocale()
。阅读文档并熟悉“The Laravel Way”会容易得多,然后事情就会按您的预期工作。
【讨论】:
【参考方案3】:我将逻辑移到控制器上,现在我的路线很简单:
Route::pattern('slug', '[a-zA-Z0-9\-_\/]+');
$slug = Request::path();
if(isset($slug))
Route::any('/slug', 'PagesController@index')->where('slug', '[a-zA-Z0-9\-_\/]+');
会话存储在 PagesController 中并在应用程序中进一步使用。谢谢你们的帮助。
【讨论】:
以上是关于Laravel 5:会话没有按应有的方式工作的主要内容,如果未能解决你的问题,请参考以下文章