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:会话没有按应有的方式工作的主要内容,如果未能解决你的问题,请参考以下文章

HTML 引导页脚未按应有的方式响应。它没有粘在底部,也没有像我编程的那样显示 100% 宽度

Laravel - 在登录时销毁现有会话

Django Rest 框架令牌认证

TableView 未按应有的方式显示

会话如何在 Laravel 5 中工作

理解 Java 中的引用; BST 的 addNode() 函数未按应有的方式运行 [重复]