内容简介:Last-Modified: 2019年5月10日14:17:34Laravel 支持多种缓存系统, 并提供了统一的api接口.(Laravel 5.5)默认支持的存储驱动包括如下:
Last-Modified: 2019年5月10日14:17:34
前言
Laravel 支持多种缓存系统, 并提供了统一的api接口.
(Laravel 5.5)默认支持的存储驱动包括如下:
- file (默认使用)
- apc
- array (数组, 测试用)
- database (关系型数据库)
- memcached
- redis
默认的缓存配置文件在 config/cache.php
参考链接:
使用
直接使用 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 来操作缓存, 对应的实际类是 Illuminate\Cache\CacheManager
缓存管理类(工厂).
Cache::xxx()
我们通过 CacheManager
类获取持有不同存储驱动的 Illuminate\Cache\Repository
类
CacheManager::store($name = null)
Repository
仓库类代理了实现存储驱动接口 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 服务提供者
//...
'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 关联的项是 Illuminate\Cache\CacheManager
, 也就是我们通过 Cache Facade 实际调用的是 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 实现了 Illuminate\Contracts\Cache\Factory
接口(↑), 即实现了一个简单工厂, 传入存储驱动名, 返回对应的驱动实例.
CacheManager实现的简单工厂接口方法:
<?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
提供了 会话级别
的实例缓存, 当解析驱动名时, 它会按如下顺序解析:
CacheManager::extend(...) CacheManager::createXxxDriver(...)
这些方法返回的实例必须是实现了 Illuminate\Contracts\Cache\Repository
接口
本质上, CacheManager
就是一个提供了 会话级别缓存
的 Repository
实例工厂, 同时它提供了一个 __call
魔术方法, 以便快速调用默认缓存驱动.
$value = Cache::store('file')->get('foo');
// 通过 _call, 调用默认缓存驱动的 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 是一个符合
PSR
-16: Common Interface for Caching
Libraries
规范的缓存仓库类, 其在Laravel相应的实现类: 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
实现了代理模式, 具体的实现是交由 Illuminate\Contracts\Cache\Store
来处理, Repository
主要作用是
- 提供一些便捷操作(可以理解为语法糖)
- Event 事件触发, 包括缓存命中/未命中、写入/删除键值
Store
Illuminate\Contracts\Cache
缓存驱动是实际处理缓存如何写入/读取/删除的类, 接口内容如下:
<?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();
}
具体的实现类有:
ApcStore ArrayStore NullStore DatabaseStore FileStore MemcachedStore RedisStore
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- YYCache 源码解析(二):磁盘缓存的设计与缓存组件设计思路
- Mybatis 缓存系统源码解析 原 荐
- Spark 源码系列(五)分布式缓存
- Android 内存缓存框架 LruCache 的源码分析
- 3种堆内缓存算法,赠源码和设计思路
- RecyclerView 源码深入解析——绘制流程、缓存机制、动画等
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Coding the Matrix
Philip N. Klein / Newtonian Press / 2013-7-26 / $35.00
An engaging introduction to vectors and matrices and the algorithms that operate on them, intended for the student who knows how to program. Mathematical concepts and computational problems are motiva......一起来看看 《Coding the Matrix》 这本书的介绍吧!