成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Laravel 的緩存源碼解析

neroneroffy / 2087人閱讀

摘要:年月日前言支持多種緩存系統(tǒng)并提供了統(tǒng)一的接口默認(rèn)支持的存儲(chǔ)驅(qū)動(dòng)包括如下默認(rèn)使用數(shù)組測(cè)試用關(guān)系型數(shù)據(jù)庫(kù)默認(rèn)的緩存配置文件在參考鏈接使用直接使用為我們提供的支持的大部分方法其他使用方法請(qǐng)參照官方翻譯中文文檔源碼中常用

Last-Modified: 2019年5月10日14:17:34

前言

Laravel 支持多種緩存系統(tǒng), 并提供了統(tǒng)一的api接口.

(Laravel 5.5)默認(rèn)支持的存儲(chǔ)驅(qū)動(dòng)包括如下:

file (默認(rèn)使用)

apc

array (數(shù)組, 測(cè)試用)

database (關(guān)系型數(shù)據(jù)庫(kù))

memcached

redis

默認(rèn)的緩存配置文件在 config/cache.php

參考鏈接:

https://learnku.com/docs/lara...

https://www.jianshu.com/p/46a...

使用

直接使用Laravel為我們提供的Facade

use IlluminateSupportFacadesCache;
$cache = Cache::get("key");

支持的大部分方法:

Cache::put("key", "value", $minutes);
Cache::add("key", "value", $minutes);
Cache::forever("key", "value");
Cache::remember("key", $minutes, function(){ return "value" });
Cache::rememberForever("key", function(){ return "value" });
Cache::forget("key");
Cache::has("key");
Cache::get("key");
Cache::get("key", "default");
Cache::get("key", function(){ return "default"; });
Cache::tags("my-tag")->put("key","value", $minutes);
Cache::tags("my-tag")->has("key");
Cache::tags("my-tag")->get("key");
Cache::tags("my-tag")->forget("key");
Cache::tags("my-tag")->flush();
Cache::increment("key");
Cache::increment("key", $amount);
Cache::decrement("key");
Cache::decrement("key", $amount);
Cache::tags("group")->put("key", $value);
Cache::tags("group")->get("key");
Cache::tags("group")->flush();

其他使用方法請(qǐng)參照官方翻譯(中文)文檔: https://learnku.com/docs/lara...

源碼

Laravel 中常用 Cache Facade 來(lái)操作緩存, 對(duì)應(yīng)的實(shí)際類是 IlluminateCacheCacheManager 緩存管理類(工廠).

Cache::xxx()

我們通過(guò) CacheManager 類獲取持有不同存儲(chǔ)驅(qū)動(dòng)的 IlluminateCacheRepository

CacheManager::store($name = null)

Repository 倉(cāng)庫(kù)類代理了實(shí)現(xiàn)存儲(chǔ)驅(qū)動(dòng)接口 IlluminateContractsCacheStore 的類實(shí)例.

Cache Facade

首先從 Cache Facade 開(kāi)始分析, 先看一下其源碼:


在配置文件 configapp.php 中定義了 Cache 服務(wù)提供者

//...
"providers" => [
        // ......
        IlluminateCacheCacheServiceProvider::class,
        // ......
    ],
//...

IlluminateCacheCacheServiceProvider 源文件:

app->singleton("cache", function ($app) {
            return new CacheManager($app);
        });

        $this->app->singleton("cache.store", function ($app) {
            return $app["cache"]->driver();
        });

        $this->app->singleton("memcached.connector", function () {
            return new MemcachedConnector;
        });
    }
    
    // ......
}

通過(guò)上面源碼可知, Cache Facade 關(guān)聯(lián)的項(xiàng)是 IlluminateCacheCacheManager, 也就是我們通過(guò) Cache Facade 實(shí)際調(diào)用的是 CacheManager實(shí)例的方法.

CacheManager

CacheManager 實(shí)現(xiàn)了 IlluminateContractsCacheFactory 接口(↑), 即實(shí)現(xiàn)了一個(gè)簡(jiǎn)單工廠, 傳入存儲(chǔ)驅(qū)動(dòng)名, 返回對(duì)應(yīng)的驅(qū)動(dòng)實(shí)例.

CacheManager實(shí)現(xiàn)的簡(jiǎn)單工廠接口方法:

getDefaultDriver();

        return $this->stores[$name] = $this->get($name);
    }
    
    /**
     * Get the default cache driver name.
     *
     * @return string
     */
    public function getDefaultDriver()
    {
        return $this->app["config"]["cache.default"];
    }

    /**
     * Attempt to get the store from the local cache.
     *
     * @param  string  $name
     * @return IlluminateContractsCacheRepository
     */
    protected function get($name)
    {
        return $this->stores[$name] ?? $this->resolve($name);
    }

    /**
     * Resolve the given store.
     *
     * @param  string  $name
     * @return IlluminateContractsCacheRepository
     *
     * @throws InvalidArgumentException
     */
    protected function resolve($name)
    {
        $config = $this->getConfig($name);

        if (is_null($config)) {
            throw new InvalidArgumentException("Cache store [{$name}] is not defined.");
        }

        if (isset($this->customCreators[$config["driver"]])) {
            return $this->callCustomCreator($config);
        } else {
            $driverMethod = "create".ucfirst($config["driver"])."Driver";

            if (method_exists($this, $driverMethod)) {
                return $this->{$driverMethod}($config);
            } else {
                throw new InvalidArgumentException("Driver [{$config["driver"]}] is not supported.");
            }
        }
    }
    
    /**
     * Dynamically call the default driver instance.
     *
     * @param  string  $method
     * @param  array   $parameters
     * @return mixed
     */
    public function __call($method, $parameters)
    {
        return $this->store()->$method(...$parameters);
    }
}

可以看到 CacheManager 提供了會(huì)話級(jí)別的實(shí)例緩存, 當(dāng)解析驅(qū)動(dòng)名時(shí), 它會(huì)按如下順序解析:

自定義驅(qū)動(dòng): 查看是否有通過(guò) CacheManager::extend(...)自定義的驅(qū)動(dòng)

Laravel提供的驅(qū)動(dòng): 查看是否存在 CacheManager::createXxxDriver(...)方法

這些方法返回的實(shí)例必須是實(shí)現(xiàn)了 IlluminateContractsCacheRepository 接口

本質(zhì)上, CacheManager 就是一個(gè)提供了會(huì)話級(jí)別緩存Repository 實(shí)例工廠, 同時(shí)它提供了一個(gè) __call 魔術(shù)方法, 以便快速調(diào)用默認(rèn)緩存驅(qū)動(dòng).

$value = Cache::store("file")->get("foo");

// 通過(guò) _call, 調(diào)用默認(rèn)緩存驅(qū)動(dòng)的 get 方法
$value = Cache::get("key");
Repository

IlluminateContractsCacheRepository 接口


Repository 是一個(gè)符合 PSR-16: Common Interface for Caching Libraries 規(guī)范的緩存?zhèn)}庫(kù)類, 其在Laravel相應(yīng)的實(shí)現(xiàn)類: IlluminateCacheRepository

IlluminateCacheRepository 部分代碼如下:

store = $store;
    }

    public function has($key)
    {
        return ! is_null($this->get($key));
    }

    public function get($key, $default = null)
    {
        if (is_array($key)) {
            return $this->many($key);
        }

        $value = $this->store->get($this->itemKey($key));

        // If we could not find the cache value, we will fire the missed event and get
        // the default value for this cache value. This default could be a callback
        // so we will execute the value function which will resolve it if needed.
        if (is_null($value)) {
            $this->event(new CacheMissed($key));

            $value = value($default);
        } else {
            $this->event(new CacheHit($key, $value));
        }

        return $value;
    }

    public function pull($key, $default = null)
    {
        return tap($this->get($key, $default), function ($value) use ($key) {
            $this->forget($key);
        });
    }
    
    protected function event($event)
    {
        if (isset($this->events)) {
            $this->events->dispatch($event);
        }
    }

    /**
     * Set the event dispatcher instance.
     *
     * @param  IlluminateContractsEventsDispatcher  $events
     * @return void
     */
    public function setEventDispatcher(Dispatcher $events)
    {
        $this->events = $events;
    }

    public function __call($method, $parameters)
    {
        if (static::hasMacro($method)) {
            return $this->macroCall($method, $parameters);
        }

        return $this->store->$method(...$parameters);
    }
    
    public function __clone()
    {
        $this->store = clone $this->store;
    }
}

從源碼可以看出, IlluminateCacheRepository 實(shí)現(xiàn)了代理模式, 具體的實(shí)現(xiàn)是交由 IlluminateContractsCacheStore 來(lái)處理, Repository 主要作用是

提供一些便捷操作(可以理解為語(yǔ)法糖)

Event 事件觸發(fā), 包括緩存命中/未命中、寫入/刪除鍵值

Store

IlluminateContractsCache 緩存驅(qū)動(dòng)是實(shí)際處理緩存如何寫入/讀取/刪除的類, 接口內(nèi)容如下:


具體的實(shí)現(xiàn)類有:

ApcStore

ArrayStore

NullStore

DatabaseStore

FileStore

MemcachedStore

RedisStore

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/62106.html

相關(guān)文章

  • Laravel 緩存源碼解析

    摘要:年月日前言支持多種緩存系統(tǒng)并提供了統(tǒng)一的接口默認(rèn)支持的存儲(chǔ)驅(qū)動(dòng)包括如下默認(rèn)使用數(shù)組測(cè)試用關(guān)系型數(shù)據(jù)庫(kù)默認(rèn)的緩存配置文件在參考鏈接使用直接使用為我們提供的支持的大部分方法其他使用方法請(qǐng)參照官方翻譯中文文檔源碼中常用 Last-Modified: 2019年5月10日14:17:34 前言 Laravel 支持多種緩存系統(tǒng), 并提供了統(tǒng)一的api接口. (Laravel 5.5)默認(rèn)支持的...

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

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

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

    摘要:源碼解析這個(gè)類的源碼主要就是文件的操作和文件屬性的操作,而具體的操作是通過(guò)每一個(gè)實(shí)現(xiàn)的,看其構(gòu)造函數(shù)看以上代碼知道對(duì)于操作,實(shí)際上是通過(guò)的實(shí)例來(lái)實(shí)現(xiàn)的??梢钥聪碌氖褂蒙衔囊呀?jīng)說(shuō)了,使得對(duì)各種的操作變得更方便了,不管是還是得。 說(shuō)明:本文主要學(xué)習(xí)下LeagueFlysystem這個(gè)Filesystem Abstract Layer,學(xué)習(xí)下這個(gè)package的設(shè)計(jì)思想和編碼技巧,把自己的一...

    Luosunce 評(píng)論0 收藏0
  • Laravel框架門面Facade源碼分析

    摘要:容器主要的作用就是生產(chǎn)各種零件,就是提供各個(gè)服務(wù)。的原理我們以為例,來(lái)講解一下門面的原理與實(shí)現(xiàn)。當(dāng)運(yùn)行時(shí),發(fā)現(xiàn)門面沒(méi)有靜態(tài)函數(shù),就會(huì)調(diào)用這個(gè)魔術(shù)函數(shù)。我們看到這個(gè)魔術(shù)函數(shù)做了兩件事獲得對(duì)象實(shí)例,利用對(duì)象調(diào)用函數(shù)。 前言 在開(kāi)始之前,歡迎關(guān)注我自己的博客:www.leoyang90.cn這篇文章我們開(kāi)始講 laravel 框架中的門面 Facade,什么是門面呢?官方文檔: Facade...

    wanghui 評(píng)論0 收藏0
  • Laravel核心解讀--服務(wù)提供器(ServiceProvider)

    摘要:調(diào)用了的可以看出,所有服務(wù)提供器都在配置文件文件的數(shù)組中。啟動(dòng)的啟動(dòng)由類負(fù)責(zé)引導(dǎo)應(yīng)用的屬性中記錄的所有服務(wù)提供器,就是依次調(diào)用這些服務(wù)提供器的方法,引導(dǎo)完成后就代表應(yīng)用正式啟動(dòng)了,可以開(kāi)始處理請(qǐng)求了。 服務(wù)提供器是所有 Laravel 應(yīng)用程序引導(dǎo)中心。你的應(yīng)用程序自定義的服務(wù)、第三方資源包提供的服務(wù)以及 Laravel 的所有核心服務(wù)都是通過(guò)服務(wù)提供器進(jìn)行注冊(cè)(register)和引...

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

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

0條評(píng)論

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