这两天遇到了一个很奇怪的问题,更新sessionsession的值不变。经过一番追查,终于找到问题,并搞明白了原理。写这篇博客记录下。

框架版本

Laravel 5.4

问题

先来描述下问题,我在我们项目基础的Middleware中,加入session操作,存入了一个值,再在Controller中取出使用,大致代码如下:

// Middleware
public function handle($request, Closure $next)
{$id = Redis::get('id');session(['id' => $id]);return $next($request);
}// Controller
public function index()
{$id = session('id');return ['id' => $id];
}

假设reids中的id是1,这一次访问index这个action,返回的是1,当你将redisid的值改成2时,在访问,发现返回的还是1,而且之后的访问也都是1。这里说明一下session使用的是redis

解决问题

看到这样神奇的结果,百思不得其解。于是打开Xdebug,开始调试。经过多次调试,发现在执行完
\Illuminate\Session\Middleware\StartSession这个Middleware后,session里面的值就变回1了,在之前都是2。然后想到会不会我们的MiddlewareStartSession之前执行造成的,将我们的Middleware移到StartSession之后,发现果然可以了,app/Http/Kernel.php中的代码如下:

protected $middlewareGroups = ['web' => [\Illuminate\Cookie\Middleware\EncryptCookies::class,\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,\Illuminate\Session\Middleware\StartSession::class,\Illuminate\View\Middleware\ShareErrorsFromSession::class,\Illuminate\Routing\Middleware\SubstituteBindings::class,\App\Http\Middleware\OurMiddleware::class,]
];

其中的OurMiddleware是我们自己写的Middleware,之前是放在最上面的,$next($request)之前的代码的执行顺序是从上到下的,如果OurMiddleware中有些内容是必须在最开始的,可以考虑分成两个Middleware

理解原理

虽然解决了问题,但还是不知道其原理究竟是怎样的,带着这样的疑问我继续查看源码,最终找到了相应的内容。

  • session不是实时落地的,也就是说当你调用session(['id' => $id])时,id并没有被真正存入redis中,而是缓存在 \Illuminate\Session\Store单例的attributes属性中,可以查看其put方法,代码如下:
    ```php
    public function put($key, $value = null)
    {
    if (! is_array($key)) {
    $key = [$key => $value];
    }

      foreach ($key as $arrayKey => $arrayValue) {Arr::set($this->attributes, $arrayKey, $arrayValue);}

    }
    ```

  • \Illuminate\Session\Middleware\StartSession在执行时,回自动加载redis中已经实例化的数据,并覆盖\Illuminate\Session\Store单例中的attributes属性,所以这就导致我们一直取到的都是redis中的session数据。加载覆盖的代码如下:

    protected function loadSession()
    {$this->attributes = array_merge($this->attributes, $this->readFromHandler());
    }
    protected function readFromHandler()
    {if ($data = $this->handler->read($this->getId())) {$data = @unserialize($this->prepareForUnserialize($data));if ($data !== false && ! is_null($data) && is_array($data)) {return $data;}}return [];
    }

其中的readFromHandler方法就是获取redis中的session数据。

后记

其实这不是Laravel session的坑,是我自己踩坑,原谅我是个标题党

转载于:https://www.cnblogs.com/CraryPrimitiveMan/p/6654674.html

Laravel Session 遇到的坑相关推荐

  1. laravel用redis保存session遇到的坑,没报错,但redis-cli就是查不到

    laravel用redis保存session遇到的坑, 配置redis存储session流程是这样的 在.evn文件中把session驱动和连接改为了redis的 如下: SESSION_DRIVER ...

  2. laravel session redis 设置

    Laravel 在使用 Redis 作为 Session 驱动之前, 需要通过 Composer 安装 predis/predis 扩展包 (~1.0). 当然也可以用原生自带的,具体使用见 http ...

  3. mac下php的坑,MAC下安装laravel时遇到的坑

    php版本:php7.0 服务器:nginx OS:OS X EI Capitan 首先安装composer 通过composer 来安装laravel 1,首先切换到你的根目录 运行以下代码 com ...

  4. 从Github下载laravel项目遇到的坑

    直接从领导给的地址拉下来的项目,先来研究下这个项目,结果,本地环境下打开发现错误多多,这是第一次从github搞项目下来,缺乏经验. Parseerror:syntaxerror,unexpected ...

  5. 从github下载laravel项目碰到的坑

    今天从github下载了一个laravel项目的zip包,准备研究下这个项目,结果,本地环境下打开发现错误多多,这是第一次从github搞项目下来,缺乏经验. 问题描述 Warning: requir ...

  6. laravel map方法踩坑记录

    用map方法编辑集合的时候,集合中存在关联查询结果是相同的时候,进行修改回出现修改A会影响B的情况 例如 代码逻辑 //以下数据遍历第一次的时候,修改$item新增属性node_type,会影响第二次 ...

  7. 注意:阿里Druid连接池监控的两个坑

    image 阿里的Druid大家都知道是最好的连接池,其强大的监控功能是我们追求的重要特性.但在实际情况中也有不少坑,说下最近遇到的一个坑吧! 问题1:不断打印error级别的错误日志 session ...

  8. HTTP层 —— Session

    1.简介 由于HTTP驱动的应用是无状态的,所以我们使用来存储用户请求信息.通过干净.统一的API处理后端各种Session驱动,目前支持的流行后端驱动包括.和. 配置 Session配置文件位于co ...

  9. 手把手教你Homestead安装,并填坑!!

    来源:http://www.jianshu.com/p/ae9d1261bbd8 话说作为laravel的开发者,你听说Homestead应该很久了,可是官方推荐的开发环境在国内为什么鲜有人用?我这几 ...

最新文章

  1. Scott Mitchell 的ASP.NET 2.0数据教程之十一: 基于数据的自定义格式化
  2. unity3d 自动变化大小_一种可扩展的Unity3d资源检查方式
  3. 异步导致UI句柄增加的解决办法
  4. linux 查找某目录下包含关键字内容的文件(文件内容、grep)
  5. 缓冲区溢出攻击-C语言中的危险函数
  6. 两行Python代码实现电影打分与推荐
  7. python下载文件并改名_Python遍历文件夹并批量改名
  8. 零基础快速入门web学习路线(含视频教程)
  9. css3 之弹性布局
  10. python 字符串替换_python字符串替换的2种方法
  11. Flutter实战:手把手教你写Flutter Plugin
  12. mock模拟接口测试_Python接口测试之mock(上)
  13. 任学堂说科技:穿越计算机迷雾,从零开始构建计算机
  14. 任天堂switch底座带网口全新方案分享
  15. Mark loves cat
  16. iPad上的数学软件介绍与畅想
  17. 三个案例详解不同网段之间如何互通
  18. 工具_SETUNA2、3下载,截图小工具,SETUNA github下载
  19. Vue 组件封装之 Content 列表(处理多行输入框 textarea)
  20. 何止VR,新闻业迎来五大新技术变革

热门文章

  1. 广度优先搜索(BFS)
  2. 查看并设置oracle并发连接数
  3. JAVA程序员面试必知32个知识点
  4. WorldWind源码剖析系列:可渲染对象类RenderableObject
  5. C# mysql 插入数据,中文乱码
  6. asp.net MD5加密函数(c#)
  7. 安装容器编排工具 Docker Compose
  8. 架构师之路17年精选80篇
  9. c# nat udp转发
  10. python学习中遇到的问题