亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

Laravel學(xué)習(xí)筆記之Session源碼解析(下)

Awbeci / 2074人閱讀

摘要:實際上,在中關(guān)閉主要包括兩個過程保存當(dāng)前到介質(zhì)中在中存入。,學(xué)習(xí)下關(guān)閉的源碼吧先??傊?,關(guān)閉的第二件事就是給添加。通過對的源碼分析可看出共分為三大步啟動操作關(guān)閉??偨Y(jié)本小系列主要學(xué)習(xí)了的源碼,學(xué)習(xí)了的三大步。

說明:在中篇中學(xué)習(xí)了session的CRUD增刪改查操作,本篇主要學(xué)習(xí)關(guān)閉session的相關(guān)源碼。實際上,在Laravel5.3中關(guān)閉session主要包括兩個過程:保存當(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作為存儲介質(zhì)
        if ($this->sessionConfigured()) {
            // 存儲當(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做了兩件事:存儲當(dāng)前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所需要的各個參數(shù)值為:

(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構(gòu)造函數(shù)中使用setId()設(shè)置$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中默認(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",等會看下響應(yīng)頭
"/session" = $config["path"]

(5) $config["domain"]

// 這里在config/session.php中設(shè)置成"session_domain",等會看下響應(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)境配置你的路由)簡單輸出個字符串"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。

通過對Laravel Session的源碼分析可看出Session共分為三大步:啟動Session;操作Session;關(guān)閉Session。啟動Session包括Store實例化,從存儲介質(zhì)中如redis讀取session數(shù)據(jù),和垃圾回收;操作Session包括對Session的CRUD增刪改查操作;關(guān)閉Session包括存儲當(dāng)前的URL和往Response Header添加Cookie。

總結(jié):本小系列主要學(xué)習(xí)了Laravel Session的源碼,學(xué)習(xí)了Session的三大步。后續(xù)有好的技術(shù)再分享吧,到時見。

歡迎關(guān)注Laravel-China。

RightCapital招聘Laravel DevOps

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/21941.html

相關(guān)文章

  • Laravel學(xué)習(xí)筆記Session源碼解析(中)

    摘要:說明在上篇中學(xué)習(xí)了的啟動過程,主要分為兩步,一是的實例化,即的實例化二是從存儲介質(zhì)中讀取的數(shù)據(jù)。第二步就是操作,包括對數(shù)據(jù)的增刪改查操作,本文也主要聊下相關(guān)操作源碼。下篇再學(xué)習(xí)下關(guān)閉,到時見。 說明:在上篇中學(xué)習(xí)了session的啟動過程,主要分為兩步,一是session的實例化,即IlluminateSessionStore的實例化;二是從session存儲介質(zhì)redis中讀取id ...

    longshengwang 評論0 收藏0
  • Laravel學(xué)習(xí)筆記Session源碼解析(上)

    摘要:然后中間件使用方法來啟動獲取實例,使用類來管理主要分為兩步獲取實例,主要步驟是通過該實例從存儲介質(zhì)中讀取該次請求所需要的數(shù)據(jù),主要步驟是。 說明:本文主要通過學(xué)習(xí)Laravel的session源碼學(xué)習(xí)Laravel是如何設(shè)計session的,將自己的學(xué)習(xí)心得分享出來,希望對別人有所幫助。Laravel在web middleware中定義了session中間件IlluminateSess...

    NervosNetwork 評論0 收藏0
  • Laravel學(xué)習(xí)筆記bootstrap源碼解析

    摘要:總結(jié)本文主要學(xué)習(xí)了啟動時做的七步準(zhǔn)備工作環(huán)境檢測配置加載日志配置異常處理注冊注冊啟動。 說明:Laravel在把Request通過管道Pipeline送入中間件Middleware和路由Router之前,還做了程序的啟動Bootstrap工作,本文主要學(xué)習(xí)相關(guān)源碼,看看Laravel啟動程序做了哪些具體工作,并將個人的研究心得分享出來,希望對別人有所幫助。Laravel在入口index...

    xiaoxiaozi 評論0 收藏0
  • Laravel學(xué)習(xí)筆記IoC Container實例化源碼解析

    摘要:說明本文主要學(xué)習(xí)容器的實例化過程,主要包括等四個過程??聪碌脑创a如果是數(shù)組,抽取別名并且注冊到中,上文已經(jīng)討論實際上就是的。 說明:本文主要學(xué)習(xí)Laravel容器的實例化過程,主要包括Register Base Bindings, Register Base Service Providers , Register Core Container Aliases and Set the ...

    ningwang 評論0 收藏0
  • Laravel學(xué)習(xí)筆記Container源碼解析

    摘要:實際上的綁定主要有三種方式且只是一種的,這些已經(jīng)在學(xué)習(xí)筆記之實例化源碼解析聊過,其實現(xiàn)方法并不復(fù)雜。從以上源碼發(fā)現(xiàn)的反射是個很好用的技術(shù),這里給出個,看下能干些啥打印結(jié)果太長了,就不粘貼了。 說明:本文主要學(xué)習(xí)Laravel中Container的源碼,主要學(xué)習(xí)Container的綁定和解析過程,和解析過程中的依賴解決。分享自己的研究心得,希望對別人有所幫助。實際上Container的綁...

    huayeluoliuhen 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<