摘要:實(shí)際上,在中關(guān)閉主要包括兩個(gè)過程保存當(dāng)前到介質(zhì)中在中存入。,學(xué)習(xí)下關(guān)閉的源碼吧先??傊P(guān)閉的第二件事就是給添加。通過對(duì)的源碼分析可看出共分為三大步啟動(dòng)操作關(guān)閉??偨Y(jié)本小系列主要學(xué)習(xí)了的源碼,學(xué)習(xí)了的三大步。
說明:在中篇中學(xué)習(xí)了session的CRUD增刪改查操作,本篇主要學(xué)習(xí)關(guān)閉session的相關(guān)源碼。實(shí)際上,在Laravel5.3中關(guān)閉session主要包括兩個(gè)過程:保存當(dāng)前URL到session介質(zhì)中;在Response Header中存入cookie。其中,Laravel5.3把垃圾回收提前到了中間件的前置操作,中篇有聊到。OK,學(xué)習(xí)下關(guān)閉session的源碼吧先。
開發(fā)環(huán)境:Laravel5.3 + PHP7
關(guān)閉Session首先看下IlluminateSessionMiddlewareStartSession::class中間件源碼的handle()方法:
public function handle($request, Closure $next) { ... $response = $next($request); // 檢查config/session.php中"driver"是否設(shè)置,這里已經(jīng)假設(shè)是redis作為存儲(chǔ)介質(zhì) if ($this->sessionConfigured()) { // 存儲(chǔ)當(dāng)前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")); }
從源碼中可知關(guān)閉session做了兩件事:存儲(chǔ)當(dāng)前URL;往Response Header中添加cookie。
OK,先看第一件事:
// IlluminateSessionMiddlewareStartSession protected function storeCurrentUrl(Request $request, $session) { // 如果是GET,并且不是ajax,且route對(duì)象不能為空 if ($request->method() === "GET" && $request->route() && ! $request->ajax()) { $session->setPreviousUrl($request->fullUrl()); } } public function setPreviousUrl($url) { // 使用中篇聊到的put()方法更新式存儲(chǔ)$url, // 如sentry.app:8888/session,存入到redis中的"laravel:_previous.url" $this->put("_previous.url", $url); }
所以第一件事很簡(jiǎn)單,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存儲(chǔ)作為handler,這里是使用redis作為handler protected function usingCookieSessions() { if (! $this->sessionConfigured()) { return false; } return $this->manager->driver()->getHandler() instanceof CookieSessionHandler; } // 檢查是不是永久存儲(chǔ),array不是永久存儲(chǔ),這里使用redis是永久存儲(chǔ) protected function sessionIsPersistent(array $config = null) { $config = $config ?: $this->manager->getSessionConfig(); return ! in_array($config["driver"], [null, "array"]); }
第二件事也很簡(jiǎn)單,實(shí)例化SymfonyComponentHttpFoundationCookie,并存入到response header中。其中,實(shí)例化Cookie所需要的各個(gè)參數(shù)值為:
(1) $session->getName()
// $session就是IlluminateSessionStore對(duì)象 // 在實(shí)例化Store對(duì)象時(shí),傳入的name值是讀取的app["config"]["session.cookie"] // 見 IlluminateSessionSessionManager::buildSession() line 178 "laravel_session" = $session->getName();
(2) $session->getId()
// 在實(shí)例化Store時(shí),傳入的$id=null,則在Store構(gòu)造函數(shù)中使用setId()設(shè)置$id值 //看下Store::setId()源碼就知道id是隨機(jī)生成的長(zhǎng)度為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中默認(rèn)expire_on_close = false, lifetime = 60 // 表示如果瀏覽器關(guān)閉session不過期,則保留60分鐘后再過期 protected function getCookieExpirationDate() { $config = $this->manager->getSessionConfig(); return $config["expire_on_close"] ? 0 : Carbon::now()->addMinutes($config["lifetime"]); }
(4) $config["path"]
// 默認(rèn)是"/",這是設(shè)置"/session",等會(huì)看下響應(yīng)頭 "/session" = $config["path"]
(5) $config["domain"]
// 這里在config/session.php中設(shè)置成"session_domain",等會(huì)看下響應(yīng)頭 "session_domain" = $config["domain"]
(6) Arr::get($config, "secure", false)
// 就默認(rèn)值false false = Arr::get($config, "secure", false)
(7) Arr::get($config, "http_only", true)
// 就默認(rèn)值true true = Arr::get($config, "http_only", true)
這里輸入路由sentry.app:8888/session(在本地環(huán)境配置你的路由)簡(jiǎn)單輸出個(gè)字符串"session",主要看下響應(yīng)頭是不是設(shè)置了配置的cookie值:
看下響應(yīng)頭設(shè)置了"laravel_session" cookie,并且"path","domain"是剛剛在session.php中設(shè)置的"/session","session_domain"值??傊?,Laravel關(guān)閉session的第二件事就是給Response Header添加"laravel_session" cookie。
通過對(duì)Laravel Session的源碼分析可看出Session共分為三大步:?jiǎn)?dòng)Session;操作Session;關(guān)閉Session。啟動(dòng)Session包括Store實(shí)例化,從存儲(chǔ)介質(zhì)中如redis讀取session數(shù)據(jù),和垃圾回收;操作Session包括對(duì)Session的CRUD增刪改查操作;關(guān)閉Session包括存儲(chǔ)當(dāng)前的URL和往Response Header添加Cookie。
總結(jié):本小系列主要學(xué)習(xí)了Laravel Session的源碼,學(xué)習(xí)了Session的三大步。后續(xù)有好的技術(shù)再分享吧,到時(shí)見。
歡迎關(guān)注Laravel-China。
RightCapital招聘Laravel DevOps
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/21941.html
摘要:說明在上篇中學(xué)習(xí)了的啟動(dòng)過程,主要分為兩步,一是的實(shí)例化,即的實(shí)例化二是從存儲(chǔ)介質(zhì)中讀取的數(shù)據(jù)。第二步就是操作,包括對(duì)數(shù)據(jù)的增刪改查操作,本文也主要聊下相關(guān)操作源碼。下篇再學(xué)習(xí)下關(guān)閉,到時(shí)見。 說明:在上篇中學(xué)習(xí)了session的啟動(dòng)過程,主要分為兩步,一是session的實(shí)例化,即IlluminateSessionStore的實(shí)例化;二是從session存儲(chǔ)介質(zhì)redis中讀取id ...
摘要:然后中間件使用方法來啟動(dòng)獲取實(shí)例,使用類來管理主要分為兩步獲取實(shí)例,主要步驟是通過該實(shí)例從存儲(chǔ)介質(zhì)中讀取該次請(qǐng)求所需要的數(shù)據(jù),主要步驟是。 說明:本文主要通過學(xué)習(xí)Laravel的session源碼學(xué)習(xí)Laravel是如何設(shè)計(jì)session的,將自己的學(xué)習(xí)心得分享出來,希望對(duì)別人有所幫助。Laravel在web middleware中定義了session中間件IlluminateSess...
摘要:總結(jié)本文主要學(xué)習(xí)了啟動(dòng)時(shí)做的七步準(zhǔn)備工作環(huán)境檢測(cè)配置加載日志配置異常處理注冊(cè)注冊(cè)啟動(dòng)。 說明:Laravel在把Request通過管道Pipeline送入中間件Middleware和路由Router之前,還做了程序的啟動(dòng)Bootstrap工作,本文主要學(xué)習(xí)相關(guān)源碼,看看Laravel啟動(dòng)程序做了哪些具體工作,并將個(gè)人的研究心得分享出來,希望對(duì)別人有所幫助。Laravel在入口index...
摘要:說明本文主要學(xué)習(xí)容器的實(shí)例化過程,主要包括等四個(gè)過程。看下的源碼如果是數(shù)組,抽取別名并且注冊(cè)到中,上文已經(jīng)討論實(shí)際上就是的。 說明:本文主要學(xué)習(xí)Laravel容器的實(shí)例化過程,主要包括Register Base Bindings, Register Base Service Providers , Register Core Container Aliases and Set the ...
摘要:實(shí)際上的綁定主要有三種方式且只是一種的,這些已經(jīng)在學(xué)習(xí)筆記之實(shí)例化源碼解析聊過,其實(shí)現(xiàn)方法并不復(fù)雜。從以上源碼發(fā)現(xiàn)的反射是個(gè)很好用的技術(shù),這里給出個(gè),看下能干些啥打印結(jié)果太長(zhǎng)了,就不粘貼了。 說明:本文主要學(xué)習(xí)Laravel中Container的源碼,主要學(xué)習(xí)Container的綁定和解析過程,和解析過程中的依賴解決。分享自己的研究心得,希望對(duì)別人有所幫助。實(shí)際上Container的綁...
閱讀 2190·2021-09-22 10:56
閱讀 1492·2021-09-07 10:11
閱讀 1813·2019-08-30 15:54
閱讀 2299·2019-08-30 15:44
閱讀 2318·2019-08-29 12:40
閱讀 3040·2019-08-28 18:25
閱讀 1750·2019-08-26 10:24
閱讀 3195·2019-08-23 18:39