摘要:實際上,在中關閉主要包括兩個過程保存當前到介質中在中存入。,學習下關閉的源碼吧先。總之,關閉的第二件事就是給添加。通過對的源碼分析可看出共分為三大步啟動操作關閉。總結本小系列主要學習了的源碼,學習了的三大步。
說明:在中篇中學習了session的CRUD增刪改查操作,本篇主要學習關閉session的相關源碼。實際上,在Laravel5.3中關閉session主要包括兩個過程:保存當前URL到session介質中;在Response Header中存入cookie。其中,Laravel5.3把垃圾回收提前到了中間件的前置操作,中篇有聊到。OK,學習下關閉session的源碼吧先。
開發環境:Laravel5.3 + PHP7
關閉Session首先看下IlluminateSessionMiddlewareStartSession::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,先看第一件事:
// IlluminateSessionMiddlewareStartSession 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"]); }
第二件事也很簡單,實例化SymfonyComponentHttpFoundationCookie,并存入到response header中。其中,實例化Cookie所需要的各個參數值為:
(1) $session->getName()
// $session就是IlluminateSessionStore對象 // 在實例化Store對象時,傳入的name值是讀取的app["config"]["session.cookie"] // 見 IlluminateSessionSessionManager::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)
// 就默認值false false = Arr::get($config, "secure", false)
(7) Arr::get($config, "http_only", true)
// 就默認值true true = 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的三大步。后續有好的技術再分享吧,到時見。
歡迎關注Laravel-China。
RightCapital招聘Laravel DevOps
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/21941.html
摘要:說明在上篇中學習了的啟動過程,主要分為兩步,一是的實例化,即的實例化二是從存儲介質中讀取的數據。第二步就是操作,包括對數據的增刪改查操作,本文也主要聊下相關操作源碼。下篇再學習下關閉,到時見。 說明:在上篇中學習了session的啟動過程,主要分為兩步,一是session的實例化,即IlluminateSessionStore的實例化;二是從session存儲介質redis中讀取id ...
摘要:然后中間件使用方法來啟動獲取實例,使用類來管理主要分為兩步獲取實例,主要步驟是通過該實例從存儲介質中讀取該次請求所需要的數據,主要步驟是。 說明:本文主要通過學習Laravel的session源碼學習Laravel是如何設計session的,將自己的學習心得分享出來,希望對別人有所幫助。Laravel在web middleware中定義了session中間件IlluminateSess...
摘要:總結本文主要學習了啟動時做的七步準備工作環境檢測配置加載日志配置異常處理注冊注冊啟動。 說明:Laravel在把Request通過管道Pipeline送入中間件Middleware和路由Router之前,還做了程序的啟動Bootstrap工作,本文主要學習相關源碼,看看Laravel啟動程序做了哪些具體工作,并將個人的研究心得分享出來,希望對別人有所幫助。Laravel在入口index...
摘要:說明本文主要學習容器的實例化過程,主要包括等四個過程。看下的源碼如果是數組,抽取別名并且注冊到中,上文已經討論實際上就是的。 說明:本文主要學習Laravel容器的實例化過程,主要包括Register Base Bindings, Register Base Service Providers , Register Core Container Aliases and Set the ...
摘要:實際上的綁定主要有三種方式且只是一種的,這些已經在學習筆記之實例化源碼解析聊過,其實現方法并不復雜。從以上源碼發現的反射是個很好用的技術,這里給出個,看下能干些啥打印結果太長了,就不粘貼了。 說明:本文主要學習Laravel中Container的源碼,主要學習Container的綁定和解析過程,和解析過程中的依賴解決。分享自己的研究心得,希望對別人有所幫助。實際上Container的綁...
閱讀 2176·2021-09-22 10:56
閱讀 1477·2021-09-07 10:11
閱讀 1805·2019-08-30 15:54
閱讀 2296·2019-08-30 15:44
閱讀 2313·2019-08-29 12:40
閱讀 3037·2019-08-28 18:25
閱讀 1743·2019-08-26 10:24
閱讀 3191·2019-08-23 18:39