溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Laravel 中怎么緩存源碼

發(fā)布時間:2021-06-22 16:32:58 來源:億速云 閱讀:208 作者:Leah 欄目:編程語言

這期內(nèi)容當(dāng)中小編將會給大家?guī)碛嘘P(guān)Laravel 中怎么緩存源碼,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

使用

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

use Illuminate\Support\Facades\Cache;
$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();

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

源碼

Laravel 中常用 Cache Facade 來操作緩存, 對應(yīng)的實際類是 Illuminate\Cache\CacheManager 緩存管理類(工廠).

Cache::xxx()

我們通過 CacheManager 類獲取持有不同存儲驅(qū)動的 Illuminate\Cache\Repository 類

CacheManager::store($name = null)

Repository 倉庫類代理了實現(xiàn)存儲驅(qū)動接口 Illuminate\Contracts\Cache\Store 的類實例.

Cache Facade

首先從 Cache Facade 開始分析, 先看一下其源碼:

<?php

namespace Illuminate\Support\Facades;

/**
 * @see \Illuminate\Cache\CacheManager
 * @see \Illuminate\Cache\Repository
 */
class Cache extends Facade
{
    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor()
    {
        return 'cache';
    }
}

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

//...
'providers' => [
        // ......
        Illuminate\Cache\CacheServiceProvider::class,
        // ......
    ],
//...

Illuminate\Cache\CacheServiceProvider 源文件:

<?php

namespace Illuminate\Cache;

use Illuminate\Support\ServiceProvider;

class CacheServiceProvider extends ServiceProvider
{
    // ......
    
    public function register()
    {
        $this->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;
        });
    }
    
    // ......
}

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

CacheManager

<?php

namespace Illuminate\Contracts\Cache;

interface Factory
{
    /**
     * Get a cache store instance by name.
     *
     * @param  string|null  $name
     * @return \Illuminate\Contracts\Cache\Repository
     */
    public function store($name = null);
}

CacheManager 實現(xiàn)了 Illuminate\Contracts\Cache\Factory 接口(↑), 即實現(xiàn)了一個簡單工廠, 傳入存儲驅(qū)動名, 返回對應(yīng)的驅(qū)動實例.

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

<?php

namespace Illuminate\Cache;

use Closure;
use InvalidArgumentException;
use Illuminate\Contracts\Cache\Store;
use Illuminate\Contracts\Cache\Factory as FactoryContract;
use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;

/**
 * @mixin \Illuminate\Contracts\Cache\Repository
 */
class CacheManager implements FactoryContract
{
    /**
     * Get a cache store instance by name.
     *
     * @param  string|null  $name
     * @return \Illuminate\Contracts\Cache\Repository
     */
    public function store($name = null)
    {
        $name = $name ?: $this->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 \Illuminate\Contracts\Cache\Repository
     */
    protected function get($name)
    {
        return $this->stores[$name] ?? $this->resolve($name);
    }

    /**
     * Resolve the given store.
     *
     * @param  string  $name
     * @return \Illuminate\Contracts\Cache\Repository
     *
     * @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 提供了會話級別的實例緩存, 當(dāng)解析驅(qū)動名時, 它會按如下順序解析:

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

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

這些方法返回的實例必須是實現(xiàn)了 Illuminate\Contracts\Cache\Repository 接口

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

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

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

Repository

Illuminate\Contracts\Cache\Repository 接口

<?php

namespace Illuminate\Contracts\Cache;

use Closure;
use Psr\SimpleCache\CacheInterface;

interface Repository extends CacheInterface
{
    public function has($key);
    public function get($key, $default = null);
    public function pull($key, $default = null);
    public function put($key, $value, $minutes);
    public function add($key, $value, $minutes);
    public function increment($key, $value = 1);
    public function decrement($key, $value = 1);
    public function forever($key, $value);
    public function remember($key, $minutes, Closure $callback);
    public function sear($key, Closure $callback);
    public function rememberForever($key, Closure $callback);
    public function forget($key);
    public function getStore();
}

Repository 是一個符合 href="http://www.baidu.com/link?url=9LkUzilH74QMr6SuXLs5wqzeJAXlxKxOoz7qJLQSMmy8JHcYUiJj_wtVBslGK2dB">PSR-16: Common Interface for Caching Libraries 規(guī)范的緩存?zhèn)}庫類, 其在Laravel相應(yīng)的實現(xiàn)類: Illuminate\Cache\Repository

Illuminate\Cache\Repository 部分代碼如下:

<?php

namespace Illuminate\Cache;

use Closure;
use ArrayAccess;
use DateTimeInterface;
use BadMethodCallException;
use Illuminate\Support\Carbon;
use Illuminate\Cache\Events\CacheHit;
use Illuminate\Contracts\Cache\Store;
use Illuminate\Cache\Events\KeyWritten;
use Illuminate\Cache\Events\CacheMissed;
use Illuminate\Support\Traits\Macroable;
use Illuminate\Cache\Events\KeyForgotten;
use Illuminate\Support\InteractsWithTime;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Contracts\Cache\Repository as CacheContract;

/**
 * @mixin \Illuminate\Contracts\Cache\Store
 */
class Repository implements CacheContract, ArrayAccess
{
    use InteractsWithTime;
    use Macroable {
        __call as macroCall;
    }

    /**
     * The cache store implementation.
     *
     * @var \Illuminate\Contracts\Cache\Store
     */
    protected $store;

    /**
     * The event dispatcher implementation.
     *
     * @var \Illuminate\Contracts\Events\Dispatcher
     */
    protected $events;

    protected $default = 60;

    /**
     * Create a new cache repository instance.
     *
     * @param  \Illuminate\Contracts\Cache\Store  $store
     * @return void
     */
    public function __construct(Store $store)
    {
        $this->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  \Illuminate\Contracts\Events\Dispatcher  $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;
    }
}

從源碼可以看出, Illuminate\Cache\Repository 實現(xiàn)了代理模式, 具體的實現(xiàn)是交由 Illuminate\Contracts\Cache\Store 來處理, Repository 主要作用是

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

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

Store

Illuminate\Contracts\Cache 緩存驅(qū)動是實際處理緩存如何寫入/讀取/刪除的類, 接口內(nèi)容如下:

<?php

namespace Illuminate\Contracts\Cache;

interface Store
{
    public function get($key);
    public function many(array $keys);
    public function put($key, $value, $minutes);
    public function putMany(array $values, $minutes);
    public function increment($key, $value = 1);
    public function decrement($key, $value = 1);
    public function forever($key, $value);
    public function forget($key);
    public function flush();
    public function getPrefix();
}

上述就是小編為大家分享的Laravel 中怎么緩存源碼了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI