Laravel Session 遇到的坑
这两天遇到了一个很奇怪的问题,更新session ,session的值不变。经过一番追查,终于找到问题,并搞明白了原理。写这篇博客记录下。
框架版本
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,当你将redis中id的值改成2时,在访问,发现返回的还是1,而且之后的访问也都是1。这里说明一下session使用的是redis 。
解决问题
看到这样神奇的结果,百思不得其解。于是打开Xdebug,开始调试。经过多次调试,发现在执行完
\Illuminate\Session\Middleware\StartSession这个Middleware后,session里面的值就变回1了,在之前都是2。然后想到会不会我们的Middleware在StartSession之前执行造成的,将我们的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方法,代码如下:
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的坑,是我自己踩坑,原谅我是个标题党
Laravel Session 遇到的坑的更多相关文章
- laravel用redis保存session遇到的坑,没报错,但redis-cli就是查不到
laravel用redis保存session遇到的坑, 配置redis存储session流程是这样的 在.evn文件中把session驱动和连接改为了redis的 如下: SESSION_DRIVER ...
- laravel中遇到的坑
已经遇到的坑和未来可能遇到的坑都将在这里写出来: 在资源控制器中创建新的方法后(如果资源控制器中的7个方法无法满足你的需求时,你就会创建新的方法),接下来就是创建路由,这个时候注意了,你必须要把路由放 ...
- Laravel Session() 失效的问题
之前因为自己自定义了后台的路由,然后路由定义的乱七八糟的. 突然发现session失效了,记录一下,避免后者遇坑. 路由组统一通过web中间件或者存在于一个中间件中 protected $middle ...
- laravel session的几个特点
1. 只要访问了网站,就会创建一个临时的session 2.用户登录后sessionid就会发生变化 3.在这期间,即使使用4g网络,ip地址会不断发生变化,只要cookie中包含了sessionid ...
- Laravel session的保存机制
与$_SESSION不同Laraver中的session是在当次程序执行完毕时保存到文件或其他存储引擎中的,也就是说如果使用了die等强制结束程序的函数将不会自动保存session导致session失 ...
- laravel session使用 转自http://blog.csdn.net/angle_hearts/article/details/53923782
use Symfony\Component\HttpFoundation\Session\Session;//存储session $session = new Session;$session-> ...
- laravel 容器注入的坑
今天遍历添加数据时遇到个坑,哪位大神知道什么原因?? 起初的代码是这样的:(部分) public function addActive(Request $request, Activenorms $a ...
- 记录关于使用ADO.NET 连接池连接Oracle时Session信息不更新的坑
最近的一个项目中,由于界面查询的数据量比较大,关联的表比较多,有些数据查出来需要临时保存起来供后面的查询使用,于是想到了用oracle的临时表来实现这个需求.大家都知道,oracle的临时表有两种:事 ...
- Laravel学习笔记之Session源码解析(下)
说明:在中篇中学习了session的CRUD增删改查操作,本篇主要学习关闭session的相关源码.实际上,在Laravel5.3中关闭session主要包括两个过程:保存当前URL到session介 ...
随机推荐
- [Bullet3]三种碰撞检测及实现
官方文档:http://bulletphysics.org 开源代码:https://github.com/bulletphysics/bullet3/releases API文档:http://bu ...
- Java(多态练习 instanceof)
/* 题目: (多态,instanceof)有如下代码 class Animal { private String name; // 1 } class Dog extends Animal { // ...
- Htmlunit使用
//模拟一个浏览器 WebClient webClient = new WebClient(); //设置webClient的相关参数 webClient.setJavaScriptEnabled(t ...
- [MongoDB] - 数据的增删改操作
在前一篇中简单的介绍了一些基本操作命令,现在分别针对这些命令进行比较详细的说明: 一.数据插入 插入数据使用命令insert,insert的参数只有一个,就是要插入的文档BSON数据.MongoDB的 ...
- 【录教程必备】推荐几款屏幕录制工具(可录制GIF)
我们经常会遇到一些场景,需要你向别人展示一些操作或是效果——例如告诉别人某某软件的配置步骤啊.刚设计出来网站的动画效果怎么样啊.某某电影里面的一个镜头多么经典啊.打得大快人心的NBA绝杀瞬间是怎么回事 ...
- MS office2010 ppt自动放映的设置方法
在菜单“幻灯片放映”-“排练时间”,进入演示,然后设置每张幻灯片需要等待的时间后,手动切换到下一张(如图),一直放映结束,会提示你是否保存排练时间.然后在菜单“幻灯片放映”-“设置放映方式”,里面选择 ...
- Mysql删除表格之后,进行恢复
一:存在在PHPmyAdmin下找到表格导出然后再导入 二:当没有备份时,使用binlog功能进行恢复 先进入到/etc/my.cnf文件中. 在文件中添加一句:log-bin=mysql-bin 然 ...
- canvas画时钟,重拾乐趣!
canvas时钟--效果图 一.先来简单介绍画时钟需要的canvas知识 1.在HTML页面中添加canvas元素,必须定义canvas元素的id属性值以便接下来的调用. HTML代码: <ca ...
- 快速排序OC、Swift版源码
前言: 你要问我学学算法在工作当中有什么用,说实话,当达不到那个地步的时候,可能我们不能直接的感觉到它的用处!你就抱着这样一个心态,当一些APP中涉及到算法的时候我不想给其他人画界面!公司的项目也是暂 ...
- redis 扩展下载
自己保存一下 免得以后忘记还得重新找T-T http://windows.php.net/downloads/pecl/snaps/redis/2.2.5/ phpinfo查看自己的php信息下载对 ...