国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

php如何實(shí)現(xiàn)session,自己實(shí)現(xiàn)session,laravel如何實(shí)現(xiàn)session

silvertheo / 3032人閱讀

摘要:如何實(shí)現(xiàn)執(zhí)行腳本,會(huì)從中讀取配置項(xiàng),將生成的唯一值保存文件放到配置項(xiàng)中的保存路徑和地點(diǎn)。并通過協(xié)議返回響應(yīng)消息頭名值發(fā)送給客戶端。

1、php如何實(shí)現(xiàn)session
執(zhí)行php腳本,session_start()會(huì)從php.ini中讀取配置項(xiàng),將生成的唯一值sessionID保存文件放到配置項(xiàng)中的保存路徑和地點(diǎn)。并通過HTTP協(xié)議返回響應(yīng)消息頭setCookie
Cookie名=Cookie值發(fā)送給客戶端。
客戶端接受到Set-Cookie,將cookie值寫入cookie文件
在接下來的訪問中,客戶端會(huì)攜帶cookie訪問瀏覽器,瀏覽器接受到cookie值,生成http請(qǐng)求頭將包含的COOKIE發(fā)送給Php,php識(shí)別cookie值,從保存路徑中找對(duì)應(yīng)的文件。
找到文件之后,檢驗(yàn)是否在有效期內(nèi),在有效期內(nèi)就讀取文件,不再有效期內(nèi)就清空文件
2、自己實(shí)現(xiàn)session需要考慮的幾個(gè)問題 1)、生成唯一值的算法 2)、將session存到文件里還是存到redis還是memcache,應(yīng)該存什么數(shù)據(jù) 3)、接受cookie值,從保存位置找到對(duì)應(yīng)的文件或數(shù)據(jù) 4)、session垃圾回收機(jī)制,刪除session文件和數(shù)據(jù) 5)、分布式的話,session同步問題 3、分析一下laravel如何實(shí)現(xiàn)session.
vendor/laravel/framework/src/Illuminate/Contracts定義都是接口類(契約)。向開發(fā)者提供了統(tǒng)一的接口類訪問Session數(shù)據(jù)
看一下session接口定義的是什么?

實(shí)現(xiàn)接口類的具體實(shí)現(xiàn)類只有一個(gè),也被稱為驅(qū)動(dòng)器
vendor/laravel/framework/src/Illuminate/Session/Store.php

class Store implements Session
{
    protected $id;//session id

    protected $name;//session name

    protected $attributes = [];//session

    protected $handler;//會(huì)話處理程序?qū)崿F(xiàn),使用了sessionHandlerInterface接口

    protected $started = false;//會(huì)話存儲(chǔ)處理狀態(tài)
    public function __construct($name, SessionHandlerInterface $handler, $id = null)//創(chuàng)建一個(gè)新的session實(shí)例
    {
        $this->setId($id);
        $this->name = $name;
        $this->handler = $handler;
       //setId
       //$this->id = $this->isValidId($id) ? $id : $this->generateSessionId();
       //1、 $this->isValidId($id)?
              //return is_string($id) && ctype_alnum($id) && strlen($id) === 40;
              //is_string($id)檢查sessionid是不是字符串,ctype_alnum檢查sessionid所有的字符全是字母和數(shù)字,是為true,否為false;strlen檢查字符串長(zhǎng)度是否等于40
       //2、$this->generateSessionId();?
             //return Str::random(40); 這個(gè)使用Str門面類生成長(zhǎng)度為40的唯一值
       //handler使用的是php預(yù)留接口類SessionnHandlerInterface,這個(gè)接口是為了將session存儲(chǔ)到數(shù)據(jù)庫中,(難怪在laravel查半天都沒查到)。該類的回調(diào)方法是在php內(nèi)部調(diào)用。
     }
來源于vendorlaravelframeworksrcIlluminateSupportStr.php 
laravel實(shí)現(xiàn)生成session唯一值算法函數(shù),重點(diǎn)是使用了random_bytes函數(shù)和base64_encode函數(shù)
    public static function random($length = 16)
        {
          $string = "";
    
            while (($len = strlen($string)) < $length) {//當(dāng)它的長(zhǎng)度小于$length時(shí)
                $size = $length - $len;//長(zhǎng)度差
    
                $bytes = random_bytes($size);//根據(jù)size生成加密安全的偽隨機(jī)字節(jié)字符串
    
                $string .= substr(str_replace(["/", "+", "="], "", base64_encode($bytes)), 0, $size);//base64_encode對(duì)其進(jìn)行編碼,目的時(shí)為了使二進(jìn)制數(shù)據(jù)可以通過非純8比特的傳輸層傳輸,通過str_replace函數(shù)去掉字符串的/+=3種符號(hào),在用substr截取$size大小的字符串。
            }
    
            return $string;
        }
來源于php手冊(cè)中的關(guān)于SessionHandlerInterface接口的定義
SessionHandlerInterface {
/* 方法 */
    abstract public close ( void ) : bool
    abstract public destroy ( string $session_id ) : bool
    abstract public gc ( int $maxlifetime ) : int
    abstract public open ( string $save_path , string $session_name ) : bool
    abstract public read ( string $session_id ) : string
    abstract public write ( string $session_id , string $session_data ) :bool
}
看看都有那些類實(shí)現(xiàn)了SessionHandler,在編程軟件中全局搜索implements SessionHandlerInterface

//CacheBasedSessionHandler 使用的實(shí)例化對(duì)象是
Illuminate/Contracts/Cache/Repository
"cache.store" => [IlluminateCacheRepository::class,
IlluminateContractsCacheRepository::class],

//CookieSessionHandler
//DatabaseSessionHandler
//FileSessionHandler
//NullSessionHandler

   //根據(jù)session id讀取數(shù)據(jù)
    public function start()
    {
        $this->loadSession();
        //驗(yàn)證csrf_token
        if (! $this->has("_token")) {
            $this->regenerateToken();
        }

        return $this->started = true;
    }
    protected function loadSession()
    {
        //array_merge合并兩個(gè)數(shù)組
        //readFromHandler() 從驅(qū)動(dòng)器中根據(jù)session id得到session信息
        $this->attributes = array_merge($this->attributes, $this->readFromHandler());
    }
    protected function readFromHandler()
    {
        if ($data = $this->handler->read($this->getId())) {
             //@阻止警告輸出
             //unserialize反序列化讀出來的session的id信息
            $data = @unserialize($this->prepareForUnserialize($data));
            //如果數(shù)組不是錯(cuò)誤,不為空,是數(shù)組就返回?cái)?shù)據(jù)
            if ($data !== false && ! is_null($data) && is_array($data)) {
                return $data;
            }
        }

        return [];
    }
    //返回?cái)?shù)據(jù)
    protected function prepareForUnserialize($data)
    {
        return $data;
    }
public function save()
{
    $this->ageFlashData();

    $this->handler->write($this->getId(), $this->prepareForStorage(
        serialize($this->attributes)
    ));

    $this->started = false;
}
    protected function prepareForStorage($data)
    {
        return $data;
    }
    //使會(huì)話閃存存數(shù)據(jù)老化
    public function ageFlashData()
    {

        $this->forget($this->get("_flash.old", []));
        //其他文件定義的forget方法
>  public static function forget(&$array, $keys)
>     {
>         $original = &$array;
> 
>         $keys = (array) $keys;
> 
>         if (count($keys) === 0) {
>             return;
>         }
> 
>         foreach ($keys as $key) {
>             // if the exact key exists in the top-level, remove it
>             if (static::exists($array, $key)) {
>                 unset($array[$key]);
> 
>                 continue;
>             }
> 
>             $parts = explode(".", $key);
> 
>             // clean up before each pass
>             $array = &$original;
> 
>             while (count($parts) > 1) {
>                 $part = array_shift($parts);
> 
>                 if (isset($array[$part]) && is_array($array[$part])) {
>                     $array = &$array[$part];
>                 } else {
>                     continue 2;
>                 }
>             }
> 
>             unset($array[array_shift($parts)]);
>         }
>     }

        $this->put("_flash.old", $this->get("_flash.new", []));

        $this->put("_flash.new", []);
    }
    public function all()
    {
        return $this->attributes;
    }
    public function exists($key)
    {
        $placeholder = new stdClass;

        return ! collect(is_array($key) ? $key : func_get_args())->contains(function ($key) use ($placeholder) {
            return $this->get($key, $placeholder) === $placeholder;
        });
    }
    //檢查是否存在Key值
    public function has($key)
    {
        return ! collect(is_array($key) ? $key : func_get_args())->contains(function ($key) {
            return is_null($this->get($key));
        });
    }
//獲取session信息
    public function get($key, $default = null)
    {
        return Arr::get($this->attributes, $key, $default);
    }
//刪除,類似pop
    public function pull($key, $default = null)
    {
        return Arr::pull($this->attributes, $key, $default);
    }
    public function hasOldInput($key = null)
    {
        $old = $this->getOldInput($key);

        return is_null($key) ? count($old) > 0 : ! is_null($old);
    }
    public function getOldInput($key = null, $default = null)
    {
        return Arr::get($this->get("_old_input", []), $key, $default);
    }
    public function replace(array $attributes)
    {
        $this->put($attributes);
    }
//session永久保存,在不過期范圍內(nèi)
    public function put($key, $value = null)
    {
        if (! is_array($key)) {
            $key = [$key => $value];
        }

        foreach ($key as $arrayKey => $arrayValue) {
            Arr::set($this->attributes, $arrayKey, $arrayValue);
        }
    }
    public function remember($key, Closure $callback)
    {
        if (! is_null($value = $this->get($key))) {
            return $value;
        }

        return tap($callback(), function ($value) use ($key) {
            $this->put($key, $value);
        });
    }
//類似于push
    public function push($key, $value)
    {
        $array = $this->get($key, []);

        $array[] = $value;

        $this->put($key, $array);
    }
    public function increment($key, $amount = 1)
    {
        $this->put($key, $value = $this->get($key, 0) + $amount);

        return $value;
    }
    public function decrement($key, $amount = 1)
    {
        return $this->increment($key, $amount * -1);
    }
//快閃保存,只保存兩次請(qǐng)求
    public function flash(string $key, $value = true)
    {
        $this->put($key, $value);

        $this->push("_flash.new", $key);

        $this->removeFromOldFlashData([$key]);
    }
    public function now($key, $value)
    {
        $this->put($key, $value);

        $this->push("_flash.old", $key);
    }
    public function reflash()
    {
        $this->mergeNewFlashes($this->get("_flash.old", []));

        $this->put("_flash.old", []);
    }
//刷新快閃數(shù)據(jù)時(shí)間,保持到下次請(qǐng)求
    public function keep($keys = null)
    {
        $this->mergeNewFlashes($keys = is_array($keys) ? $keys : func_get_args());

        $this->removeFromOldFlashData($keys);
    }
    protected function mergeNewFlashes(array $keys)
    {
        $values = array_unique(array_merge($this->get("_flash.new", []), $keys));

        $this->put("_flash.new", $values);
    }
    protected function removeFromOldFlashData(array $keys)
    {
        $this->put("_flash.old", array_diff($this->get("_flash.old", []), $keys));
    }
    public function flashInput(array $value)
    {
        $this->flash("_old_input", $value);
    }
    public function remove($key)
    {
        return Arr::pull($this->attributes, $key);
    }
    public function forget($keys)
    {
        Arr::forget($this->attributes, $keys);
    }
   //每次flush將數(shù)組置空
    public function flush()
    {
        $this->attributes = [];
    }
    public function invalidate()
    {
        $this->flush();

        return $this->migrate(true);
    }
    public function regenerate($destroy = false)
    {
        return tap($this->migrate($destroy), function () {
            $this->regenerateToken();
        });
    }
//給session生成一個(gè)新的sessionID
    public function migrate($destroy = false)
    {
        //如果
        if ($destroy) {
            $this->handler->destroy($this->getId());
        }

        $this->setExists(false);

        $this->setId($this->generateSessionId());

        return true;
    }
     //是否啟動(dòng)
    public function isStarted()
    {
        return $this->started;
    }

    //獲取session名
    public function getName()
    {
        return $this->name;
    }

   //設(shè)置session 名
    public function setName($name)
    {
        $this->name = $name;
    }
    //獲取session id
    public function getId()
    {
        return $this->id;
    }
    //如果sessionid有效,就返回有效id,如果失效就生成session id
    public function setId($id)
    {
        $this->id = $this->isValidId($id) ? $id : $this->generateSessionId();
    }
    //檢查session id
    public function isValidId($id)
    {
        return is_string($id) && ctype_alnum($id) && strlen($id) === 40;
    }
    //獲取sessionID 唯一的40長(zhǎng)度值
    protected function generateSessionId()
    {
        return Str::random(40);
    }
    //如果適用,在處理程序上設(shè)置會(huì)話的存在性
    public function setExists($value)
    {
        if ($this->handler instanceof ExistenceAwareInterface) {
            $this->handler->setExists($value);
        }
    }

   //獲取token值
    public function token()
    {
        return $this->get("_token");
    }

   //生成唯一值40,存入_token
    public function regenerateToken()
    {
        $this->put("_token", Str::random(40));
    }

   //獲取當(dāng)前url
    public function previousUrl()
    {
        return $this->get("_previous.url");
    }

    //存儲(chǔ)當(dāng)前url
    public function setPreviousUrl($url)
    {
        $this->put("_previous.url", $url);
    }

     //獲取當(dāng)前使用的驅(qū)動(dòng)器
    public function getHandler()
    {
        return $this->handler;
    }
    //返回驅(qū)動(dòng)器實(shí)例是否使CokieSessionHandler
    public function handlerNeedsRequest()
    {
        return $this->handler instanceof CookieSessionHandler;
    }
    //如果驅(qū)動(dòng)器是CookieSessionHandler,那么執(zhí)行setRequest方法
    public function setRequestOnHandler($request)
    {
        if ($this->handlerNeedsRequest()) {
            $this->handler->setRequest($request);
        }
    }
}

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/31633.html

相關(guān)文章

  • Laravel深入學(xué)習(xí)7 - 框架的擴(kuò)展

    摘要:組件擴(kuò)展通常有兩種方法向容器中綁定自己的接口實(shí)現(xiàn)痛過使用工廠模式實(shí)現(xiàn)的類注冊(cè)自己的擴(kuò)展。類庫管理類以工廠模式實(shí)現(xiàn),負(fù)責(zé)諸如緩存等驅(qū)動(dòng)的實(shí)例化。閉包須要傳入繼承自和容器的實(shí)例化對(duì)象。當(dāng)完成擴(kuò)展之后要記住中替換成自己的擴(kuò)展名稱。 聲明:本文并非博主原創(chuàng),而是來自對(duì)《Laravel 4 From Apprentice to Artisan》閱讀的翻譯和理解,當(dāng)然也不是原汁原味的翻譯,能保證9...

    yuanxin 評(píng)論0 收藏0
  • LaravelSession機(jī)制簡(jiǎn)介

    摘要:我們?cè)谶@個(gè)類中的方法看到如下代碼,一個(gè)典型的過濾器,在這個(gè)中獲取的方法是。,整個(gè)初始化的過程總結(jié)下巧妙的使用了面向?qū)ο蟮慕涌诜绞剑瑸槲覀兲峁┝烁鞣N各樣不同的存儲(chǔ)方式,一旦我們了解了存儲(chǔ)方式和加密規(guī)則,讓不同的容器進(jìn)行共享的目的也可以達(dá)到 前些天,為了解答一個(gè)問題,就去研究了Laravel的源碼,講講我的收獲:這個(gè)是問題源:http://segmentfault.com/q/101000...

    kelvinlee 評(píng)論0 收藏0
  • Laravel學(xué)習(xí)筆記之Decorator Pattern

    摘要:把和拼接在一起的場(chǎng)所是,所以需要造一個(gè)類,在其內(nèi)部實(shí)現(xiàn)對(duì)的操作中實(shí)現(xiàn)了把原有的進(jìn)過個(gè)的裝飾后得到的新的,新的還是的實(shí)現(xiàn),還是原來的物種。 說明:Laravel中Middleware的實(shí)現(xiàn)主要利用了Decorator Pattern的設(shè)計(jì),本文主要先學(xué)習(xí)下Decorator Pattern如何實(shí)現(xiàn),為后面學(xué)習(xí)Middleware的設(shè)計(jì)做個(gè)鋪墊。Decorator Pattern和Adap...

    dendoink 評(píng)論0 收藏0
  • 詳解 Laravel 中的依賴注入和 IoC

    摘要:依賴注入依賴注入一詞是由提出的術(shù)語,它是將組件注入到應(yīng)用程序中的一種行為。就像說的依賴注入是敏捷架構(gòu)中關(guān)鍵元素。類依賴于,所以我們的代碼可能是這樣的創(chuàng)建一個(gè)這是一種經(jīng)典的方法,讓我們從使用構(gòu)造函數(shù)注入開始。 showImg(https://segmentfault.com/img/remote/1460000018806800); 文章轉(zhuǎn)自:https://learnku.com/la...

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

    摘要:然后中間件使用方法來啟動(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...

    NervosNetwork 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<