博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Laravel学习笔记之Session源码解析(下)
阅读量:5885 次
发布时间:2019-06-19

本文共 5099 字,大约阅读时间需要 16 分钟。

说明:在中篇中学习了session的CRUD增删改查操作,本篇主要学习关闭session的相关源码。实际上,在Laravel5.3中关闭session主要包括两个过程:保存当前URL到session介质中;在Response Header中存入cookie。其中,Laravel5.3把垃圾回收提前到了中间件的前置操作,中篇有聊到。OK,学习下关闭session的源码吧先。

开发环境:Laravel5.3 + PHP7

关闭Session

首先看下\Illuminate\Session\Middleware\StartSession::class中间件源码的handle()方法:

public function handle($request, Closure $next)    {        ...            $response = $next($request);        // 检查config/session.php中'driver'是否设置,这里已经假设是redis作为存储介质        if ($this->sessionConfigured()) {            // 存储当前URL            $this->storeCurrentUrl($request, $session);            // 往Response Header中添加cookie            $this->addCookieToResponse($response, $session);        }        return $response;    }        protected function sessionConfigured()    {        return ! is_null(Arr::get($this->manager->getSessionConfig(), 'driver'));    }

从源码中可知关闭session做了两件事:存储当前URL;往Response Header中添加cookie。

OK,先看第一件事:

// \Illuminate\Session\Middleware\StartSession    protected function storeCurrentUrl(Request $request, $session)    {        // 如果是GET,并且不是ajax,且route对象不能为空        if ($request->method() === 'GET' && $request->route() && ! $request->ajax()) {            $session->setPreviousUrl($request->fullUrl());        }    }        public function setPreviousUrl($url)    {        // 使用中篇聊到的put()方法更新式存储$url,        // 如sentry.app:8888/session,存入到redis中的'laravel:_previous.url'        $this->put('_previous.url', $url);    }

所以第一件事很简单,OK,看下第二件事:

protected function addCookieToResponse(Response $response, SessionInterface $session)    {        // No, we use redis as a session handler.        if ($this->usingCookieSessions()) {            $this->manager->driver()->save();        }        // Yes, use redis as the persistent store bucket.        if ($this->sessionIsPersistent($config = $this->manager->getSessionConfig())) {            $response->headers->setCookie(new Cookie(                // 'laravel_session'                $session->getName(),                // Str::random(40)                $session->getId(),                // If it is not set to expire when the browser close. And after 60 minutes, the session will close.                $this->getCookieExpirationDate(),                // '/session'                $config['path'],                // 'session_domain'                $config['domain'],                // true                Arr::get($config, 'secure', false),                // true                Arr::get($config, 'http_only', true)            ));        }    }        // 检查是不是cookie存储作为handler,这里是使用redis作为handler    protected function usingCookieSessions()    {        if (! $this->sessionConfigured()) {            return false;        }        return $this->manager->driver()->getHandler() instanceof CookieSessionHandler;    }        // 检查是不是永久存储,array不是永久存储,这里使用redis是永久存储    protected function sessionIsPersistent(array $config = null)    {        $config = $config ?: $this->manager->getSessionConfig();        return ! in_array($config['driver'], [null, 'array']);    }

第二件事也很简单,实例化Symfony\Component\HttpFoundation\Cookie,并存入到response header中。其中,实例化Cookie所需要的各个参数值为:

(1) $session->getName()

// $session就是\Illuminate\Session\Store对象// 在实例化Store对象时,传入的name值是读取的app['config']['session.cookie']// 见 \Illuminate\Session\SessionManager::buildSession() line 178'laravel_session' = $session->getName();

(2) $session->getId()

// 在实例化Store时,传入的$id=null,则在Store构造函数中使用setId()设置$id值//看下Store::setId()源码就知道id是随机生成的长度为40的字符串Str::random(40) = $session->getId();    public function setId($id)    {        if (! $this->isValidId($id)) {            $id = $this->generateSessionId();        }        $this->id = $id;    }    public function isValidId($id)    {        return is_string($id) && ctype_alnum($id) && strlen($id) === 40;    }    protected function generateSessionId()    {        return Str::random(40);    }

(3) $this->getCookieExpirationDate()

// config/session.php中默认expire_on_close = false, lifetime = 60    // 表示如果浏览器关闭session不过期,则保留60分钟后再过期    protected function getCookieExpirationDate()    {        $config = $this->manager->getSessionConfig();        return $config['expire_on_close'] ? 0 : Carbon::now()->addMinutes($config['lifetime']);    }

(4) $config['path']

// 默认是'/',这是设置'/session',等会看下响应头'/session' = $config['path']

(5) $config['domain']

// 这里在config/session.php中设置成'session_domain',等会看下响应头'session_domain' = $config['domain']

(6) Arr::get($config, 'secure', false)

// 就默认值falsefalse = Arr::get($config, 'secure', false)

(7) Arr::get($config, 'http_only', true)

// 就默认值truetrue = Arr::get($config, 'http_only', true)

这里输入路由sentry.app:8888/session(在本地环境配置你的路由)简单输出个字符串'session',主要看下响应头是不是设置了配置的cookie值:

图片描述

看下响应头设置了'laravel_session' cookie,并且'path','domain'是刚刚在session.php中设置的'/session','session_domain'值。总之,Laravel关闭session的第二件事就是给Response Header添加'laravel_session' cookie。

通过对Laravel Session的源码分析可看出Session共分为三大步:启动Session;操作Session;关闭Session。启动Session包括Store实例化,从存储介质中如redis读取session数据,和垃圾回收;操作Session包括对Session的CRUD增删改查操作;关闭Session包括存储当前的URL和往Response Header添加Cookie。

总结:本小系列主要学习了Laravel Session的源码,学习了Session的三大步。后续有好的技术再分享吧,到时见。

欢迎关注。

招聘

转载地址:http://ozmix.baihongyu.com/

你可能感兴趣的文章
人人都会数据采集- Scrapy 爬虫框架入门
查看>>
Android网络编程11之源码解析Retrofit
查看>>
韩国SK电讯宣布成功研发量子中继器
查看>>
TCP - WAIT状态及其对繁忙的服务器的影响
查看>>
安全预警:全球13.5亿的ARRIS有线调制解调器可被远程攻击
查看>>
麦子学院与阿里云战略合作 在线教育领军者技术实力被认可
查看>>
正确看待大数据
查看>>
Facebook通过10亿单词构建有效的神经网络语言模型
查看>>
2016股市投资风向标 大数据说了算
查看>>
发展大数据不能抛弃“小数据”
查看>>
中了WannaCry病毒的电脑几乎都是Win 7
查看>>
学生机房虚拟化(九)系统操作设计思路
查看>>
nginx报错pread() returned only 0 bytes instead of 4091的分析
查看>>
质数因子
查看>>
Spring源码浅析之事务(四)
查看>>
[转载] Live Writer 配置写 CSDN、BlogBus、cnBlogs、163、sina 博客
查看>>
SQL:连表查询
查看>>
MySQL日期函数、时间函数总结(MySQL 5.X)
查看>>
c语言用尾插法新建链表和输出建好的链表
查看>>
高性能 Oracle JDBC 编程
查看>>