Laravel5.2 某些版本改动导致 session flash 用不了的坑

楼主现在项目使用的是 laravel 5.2.31版本 , 被一个小坑坑了两三个小时

简单来说 , 我在控制器某个表单提交的方法中使用validator , 跳转页面时

back()->withInput()->withError($validator);

发现withInput 和 withError 不灵了 . 在页面中打印session的数据

$request->session()->all()

看到$session->flash() 方法该存入的数据都没有了 , 真是奇怪

为了解决这个问题探索了各种方法 . 是不是validator不对?是不是控制器自带的validate()方法有问题? 是不是session 的驱动有问题? 又搜google和stackoverflow , 浪费了不少时间 .

后来在测试路由中建了个表单页和提交页 , 发现session 的flash 都是好用的 . 只是在控制器里不能用 . 这就联想到了是不是中间件出了问题 . 在系统自带的StartSession 中加入了一行代码打印$session->all() , 又意外地看到session的结果被打印了两次.

这就找到问题所在了 . 中间件 Illuminate\Session\Middleware\StartSession 被启动了两次 .

laravel运行中间件 , 是由HttpKernel先加载路由 , 然后把中间件的栈用\Illuminate\Pipelin\Pipeline 解析成一个闭包嵌套构成的管道 . 如果一个中间件被启动了两次 , 那肯定是路由调用了它两次.

最后发现问题所在了 . laravel 5.2 在某个版本升级中, 修改了 RouteServiceProvider , 更改了一个方法

public function map(Router $router)
{
    $this->mapWebRoutes($router);

    //
}

protected function mapWebRoutes(Router $router)
{
    $router->group([
        'namespace' => $this->namespace, 'middleware' => 'web',
    ], function ($router) {
        require app_path('Http/webRoutes.php');
    });
}

这是laravel给开发者做的一个示范 , 让我们知道http和api , 以及其它端可以加载不同的route文件来启动 .
这意味着laravel 可以有多个不同的bootstrap , 启动多个不同的kernel . 比如有HttpKernel , 还可以有RPCKernel或其它APIKernel , 每个Kernel 如同现在的Http 文件夹一样 ,拥有独立的路由文件 , 控制器 和中间件 . 这样就可以做到多端访问的资源隔离.

然而这个改动在RouteServiceProviders 里就把 'web' 中间件加载了 , 我从前面的版本过来 , 并不知道有这么一出, 按习惯在route.php 中仍然写的是

/**
 * 注册前端通用路由
 */
Route::group([
    'middleware' => 'web',
    'as'            =>  'frontend::',
    'domain'        =>  config('domain.frontend'),
    'namespace'     =>  'Frontend',
],$frontendCommonRoutes);

这样 'web' 组的中间件就加载了两次 , 第二次加载的StartSession 把flash 的内容清空了 .

这就是出错的原因 , 希望对其它在5.2.x 版本升级中遇到这个坑的朋友有帮助

多轮对话机器人框架 commune/chatbot 项目发布了demo测试. 微信关注CommuneChatbot 可以测试. QQ交流群: 907985715
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 7
Summer

:+1: 不错,商业项目在用 5.2?

7年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!