记录一下,省的每次忘记都要重新看下源码
dd(Cache::get(1));exit();
Cache::put(1,2,3);exit();
dd(app('cache'));
这里注入了CACHE的门面类
class CacheServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Register the service provider.
*
* @return void
*/
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;
});
}
CacheManager->createRedisDriver->put
app = $app;
}
/**
* 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 a cache driver instance.
*
* @param string $driver
* @return mixed
*/
public function driver($driver = null)
{
return $this->store($driver);
}
/**
* 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.");
}
}
}
/**
* Call a custom driver creator.
*
* @param array $config
* @return mixed
*/
protected function callCustomCreator(array $config)
{
return $this->customCreators[$config['driver']]($this->app, $config);
}
/**
* Create an instance of the APC cache driver.
*
* @param array $config
* @return \Illuminate\Cache\ApcStore
*/
protected function createApcDriver(array $config)
{
$prefix = $this->getPrefix($config);
return $this->repository(new ApcStore(new ApcWrapper, $prefix));
}
/**
* Create an instance of the array cache driver.
*
* @return \Illuminate\Cache\ArrayStore
*/
protected function createArrayDriver()
{
return $this->repository(new ArrayStore);
}
/**
* Create an instance of the file cache driver.
*
* @param array $config
* @return \Illuminate\Cache\FileStore
*/
protected function createFileDriver(array $config)
{
return $this->repository(new FileStore($this->app['files'], $config['path']));
}
/**
* Create an instance of the Memcached cache driver.
*
* @param array $config
* @return \Illuminate\Cache\MemcachedStore
*/
protected function createMemcachedDriver(array $config)
{
$prefix = $this->getPrefix($config);
$memcached = $this->app['memcached.connector']->connect(
$config['servers'],
$config['persistent_id'] ?? null,
$config['options'] ?? [],
array_filter($config['sasl'] ?? [])
);
return $this->repository(new MemcachedStore($memcached, $prefix));
}
/**
* Create an instance of the Null cache driver.
*
* @return \Illuminate\Cache\NullStore
*/
protected function createNullDriver()
{
return $this->repository(new NullStore);
}
/**
* Create an instance of the Redis cache driver.
*
* @param array $config
* @return \Illuminate\Cache\RedisStore
*/
protected function createRedisDriver(array $config)
{
$redis = $this->app['redis'];
$connection = $config['connection'] ?? 'default';
return $this->repository(new RedisStore($redis, $this->getPrefix($config), $connection));
}
/**
* Create an instance of the database cache driver.
*
* @param array $config
* @return \Illuminate\Cache\DatabaseStore
*/
protected function createDatabaseDriver(array $config)
{
$connection = $this->app['db']->connection($config['connection'] ?? null);
return $this->repository(
new DatabaseStore(
$connection, $config['table'], $this->getPrefix($config)
)
);
}
/**
* Create a new cache repository with the given implementation.
*
* @param \Illuminate\Contracts\Cache\Store $store
* @return \Illuminate\Cache\Repository
*/
public function repository(Store $store)
{
$repository = new Repository($store);
if ($this->app->bound(DispatcherContract::class)) {
$repository->setEventDispatcher(
$this->app[DispatcherContract::class]
);
}
return $repository;
}
/**
* Get the cache prefix.
*
* @param array $config
* @return string
*/
protected function getPrefix(array $config)
{
return $config['prefix'] ?? $this->app['config']['cache.prefix'];
}
/**
* Get the cache connection configuration.
*
* @param string $name
* @return array
*/
protected function getConfig($name)
{
return $this->app['config']["cache.stores.{$name}"];
}
/**
* Get the default cache driver name.
*
* @return string
*/
public function getDefaultDriver()
{
return $this->app['config']['cache.default'];
}
/**
* Set the default cache driver name.
*
* @param string $name
* @return void
*/
public function setDefaultDriver($name)
{
$this->app['config']['cache.default'] = $name;
}
/**
* Register a custom driver creator Closure.
*
* @param string $driver
* @param \Closure $callback
* @return $this
*/
public function extend($driver, Closure $callback)
{
$this->customCreators[$driver] = $callback->bindTo($this, $this);
return $this;
}
/**
* Dynamically call the default driver instance.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
return $this->store()->$method(...$parameters);
}
}
redis的门面类注入
class RedisServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->singleton('redis', function ($app) {
$config = $app->make('config')->get('database.redis');
return new RedisManager(Arr::pull($config, 'client', 'predis'), $config);
});
$this->app->bind('redis.connection', function ($app) {
return $app['redis']->connection();
});
}
class RedisManager implements Factory
{
/**
* The name of the default driver.
*
* @var string
*/
protected $driver;
/**
* The Redis server configurations.
*
* @var array
*/
protected $config;
/**
* The Redis connections.
*
* @var mixed
*/
protected $connections;
/**
* Create a new Redis manager instance.
*
* @param string $driver
* @param array $config
* @return void
*/
public function __construct($driver, array $config)
{
$this->driver = $driver;
$this->config = $config;
}
/**
* Get a Redis connection by name.
*
* @param string|null $name
* @return \Illuminate\Redis\Connections\Connection
*/
public function connection($name = null)
{
$name = $name ?: 'default';
if (isset($this->connections[$name])) {
return $this->connections[$name];
}
return $this->connections[$name] = $this->resolve($name);
}
/**
* Resolve the given connection by name.
*
* @param string|null $name
* @return \Illuminate\Redis\Connections\Connection
*
* @throws \InvalidArgumentException
*/
public function resolve($name = null)
{
$name = $name ?: 'default';
$options = $this->config['options'] ?? [];
if (isset($this->config[$name])) {
return $this->connector()->connect($this->config[$name], $options);
}
if (isset($this->config['clusters'][$name])) {
return $this->resolveCluster($name);
}
throw new InvalidArgumentException(
"Redis connection [{$name}] not configured."
);
}
/**
* Resolve the given cluster connection by name.
*
* @param string $name
* @return \Illuminate\Redis\Connections\Connection
*/
protected function resolveCluster($name)
{
$clusterOptions = $this->config['clusters']['options'] ?? [];
return $this->connector()->connectToCluster(
$this->config['clusters'][$name], $clusterOptions, $this->config['options'] ?? []
);
}
/**
* Get the connector instance for the current driver.
*
* @return \Illuminate\Redis\Connectors\PhpRedisConnector|\Illuminate\Redis\Connectors\PredisConnector
*/
protected function connector()
{
switch ($this->driver) {
case 'predis':
return new Connectors\PredisConnector;
case 'phpredis':
return new Connectors\PhpRedisConnector;
}
}
/**
* Return all of the created connections.
*
* @return array
*/
public function connections()
{
return $this->connections;
}
/**
* Pass methods onto the default Redis connection.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
return $this->connection()->{$method}(...$parameters);
}
}
Repository
store = $store;
}
/**
* Determine if an item exists in the cache.
*
* @param string $key
* @return bool
*/
public function has($key)
{
return ! is_null($this->get($key));
}
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
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;
}
/**
* Retrieve multiple items from the cache by key.
*
* Items not found in the cache will have a null value.
*
* @param array $keys
* @return array
*/
public function many(array $keys)
{
$values = $this->store->many(collect($keys)->map(function ($value, $key) {
return is_string($key) ? $key : $value;
})->values()->all());
return collect($values)->map(function ($value, $key) use ($keys) {
return $this->handleManyResult($keys, $key, $value);
})->all();
}
/**
* {@inheritdoc}
*/
public function getMultiple($keys, $default = null)
{
if (is_null($default)) {
return $this->many($keys);
}
foreach ($keys as $key) {
if (! isset($default[$key])) {
$default[$key] = null;
}
}
return $this->many($default);
}
/**
* Handle a result for the "many" method.
*
* @param array $keys
* @param string $key
* @param mixed $value
* @return mixed
*/
protected function handleManyResult($keys, $key, $value)
{
// 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));
return isset($keys[$key]) ? value($keys[$key]) : null;
}
// If we found a valid value we will fire the "hit" event and return the value
// back from this function. The "hit" event gives developers an opportunity
// to listen for every possible cache "hit" throughout this applications.
$this->event(new CacheHit($key, $value));
return $value;
}
/**
* Retrieve an item from the cache and delete it.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public function pull($key, $default = null)
{
return tap($this->get($key, $default), function ($value) use ($key) {
$this->forget($key);
});
}
/**
* Store an item in the cache.
*
* @param string $key
* @param mixed $value
* @param \DateTimeInterface|\DateInterval|float|int $minutes
* @return void
*/
public function put($key, $value, $minutes = null)
{
if (is_array($key)) {
return $this->putMany($key, $value);
}
if (! is_null($minutes = $this->getMinutes($minutes))) {
$this->store->put($this->itemKey($key), $value, $minutes);
$this->event(new KeyWritten($key, $value, $minutes));
}
}
/**
* {@inheritdoc}
*/
public function set($key, $value, $ttl = null)
{
$this->put($key, $value, $ttl);
}
/**
* Store multiple items in the cache for a given number of minutes.
*
* @param array $values
* @param \DateTimeInterface|\DateInterval|float|int $minutes
* @return void
*/
public function putMany(array $values, $minutes)
{
if (! is_null($minutes = $this->getMinutes($minutes))) {
$this->store->putMany($values, $minutes);
foreach ($values as $key => $value) {
$this->event(new KeyWritten($key, $value, $minutes));
}
}
}
/**
* {@inheritdoc}
*/
public function setMultiple($values, $ttl = null)
{
$this->putMany($values, $ttl);
}
/**
* Store an item in the cache if the key does not exist.
*
* @param string $key
* @param mixed $value
* @param \DateTimeInterface|\DateInterval|float|int $minutes
* @return bool
*/
public function add($key, $value, $minutes)
{
if (is_null($minutes = $this->getMinutes($minutes))) {
return false;
}
// If the store has an "add" method we will call the method on the store so it
// has a chance to override this logic. Some drivers better support the way
// this operation should work with a total "atomic" implementation of it.
if (method_exists($this->store, 'add')) {
return $this->store->add(
$this->itemKey($key), $value, $minutes
);
}
// If the value did not exist in the cache, we will put the value in the cache
// so it exists for subsequent requests. Then, we will return true so it is
// easy to know if the value gets added. Otherwise, we will return false.
if (is_null($this->get($key))) {
$this->put($key, $value, $minutes);
return true;
}
return false;
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int|bool
*/
public function increment($key, $value = 1)
{
return $this->store->increment($key, $value);
}
/**
* Decrement the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int|bool
*/
public function decrement($key, $value = 1)
{
return $this->store->decrement($key, $value);
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
$this->store->forever($this->itemKey($key), $value);
$this->event(new KeyWritten($key, $value, 0));
}
/**
* Get an item from the cache, or store the default value.
*
* @param string $key
* @param \DateTimeInterface|\DateInterval|float|int $minutes
* @param \Closure $callback
* @return mixed
*/
public function remember($key, $minutes, Closure $callback)
{
$value = $this->get($key);
// If the item exists in the cache we will just return this immediately and if
// not we will execute the given Closure and cache the result of that for a
// given number of minutes so it's available for all subsequent requests.
if (! is_null($value)) {
return $value;
}
$this->put($key, $value = $callback(), $minutes);
return $value;
}
/**
* Get an item from the cache, or store the default value forever.
*
* @param string $key
* @param \Closure $callback
* @return mixed
*/
public function sear($key, Closure $callback)
{
return $this->rememberForever($key, $callback);
}
/**
* Get an item from the cache, or store the default value forever.
*
* @param string $key
* @param \Closure $callback
* @return mixed
*/
public function rememberForever($key, Closure $callback)
{
$value = $this->get($key);
// If the item exists in the cache we will just return this immediately and if
// not we will execute the given Closure and cache the result of that for a
// given number of minutes so it's available for all subsequent requests.
if (! is_null($value)) {
return $value;
}
$this->forever($key, $value = $callback());
return $value;
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return bool
*/
public function forget($key)
{
return tap($this->store->forget($this->itemKey($key)), function () use ($key) {
$this->event(new KeyForgotten($key));
});
}
/**
* {@inheritdoc}
*/
public function delete($key)
{
return $this->forget($key);
}
/**
* {@inheritdoc}
*/
public function deleteMultiple($keys)
{
foreach ($keys as $key) {
$this->forget($key);
}
return true;
}
/**
* {@inheritdoc}
*/
public function clear()
{
return $this->store->flush();
}
/**
* Begin executing a new tags operation if the store supports it.
*
* @param array|mixed $names
* @return \Illuminate\Cache\TaggedCache
*
* @throws \BadMethodCallException
*/
public function tags($names)
{
if (! method_exists($this->store, 'tags')) {
throw new BadMethodCallException('This cache store does not support tagging.');
}
$cache = $this->store->tags($names);
if (! is_null($this->events)) {
$cache->setEventDispatcher($this->events);
}
return $cache->setDefaultCacheTime($this->default);
}
/**
* Format the key for a cache item.
*
* @param string $key
* @return string
*/
protected function itemKey($key)
{
return $key;
}
/**
* Get the default cache time.
*
* @return float|int
*/
public function getDefaultCacheTime()
{
return $this->default;
}
/**
* Set the default cache time in minutes.
*
* @param float|int $minutes
* @return $this
*/
public function setDefaultCacheTime($minutes)
{
$this->default = $minutes;
return $this;
}
/**
* Get the cache store implementation.
*
* @return \Illuminate\Contracts\Cache\Store
*/
public function getStore()
{
return $this->store;
}
/**
* Fire an event for this cache instance.
*
* @param string $event
* @return void
*/
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;
}
/**
* Determine if a cached value exists.
*
* @param string $key
* @return bool
*/
public function offsetExists($key)
{
return $this->has($key);
}
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function offsetGet($key)
{
return $this->get($key);
}
/**
* Store an item in the cache for the default time.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function offsetSet($key, $value)
{
$this->put($key, $value, $this->default);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return void
*/
public function offsetUnset($key)
{
$this->forget($key);
}
/**
* Calculate the number of minutes with the given duration.
*
* @param \DateTimeInterface|\DateInterval|float|int $duration
* @return float|int|null
*/
protected function getMinutes($duration)
{
$duration = $this->parseDateInterval($duration);
if ($duration instanceof DateTimeInterface) {
$duration = Carbon::now()->diffInRealSeconds($duration, false) / 60;
}
return (int) ($duration * 60) > 0 ? $duration : null;
}
/**
* Handle dynamic calls into macros or pass missing methods to the store.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
if (static::hasMacro($method)) {
return $this->macroCall($method, $parameters);
}
return $this->store->$method(...$parameters);
}
/**
* Clone cache repository instance.
*
* @return void
*/
public function __clone()
{
$this->store = clone $this->store;
}
}
RedisStore缓存STORE
redis = $redis;
$this->setPrefix($prefix);
$this->setConnection($connection);
}
/**
* Retrieve an item from the cache by key.
*
* @param string|array $key
* @return mixed
*/
public function get($key)
{
$value = $this->connection()->get($this->prefix.$key);
return ! is_null($value) ? $this->unserialize($value) : null;
}
/**
* Retrieve multiple items from the cache by key.
*
* Items not found in the cache will have a null value.
*
* @param array $keys
* @return array
*/
public function many(array $keys)
{
$results = [];
$values = $this->connection()->mget(array_map(function ($key) {
return $this->prefix.$key;
}, $keys));
foreach ($values as $index => $value) {
$results[$keys[$index]] = ! is_null($value) ? $this->unserialize($value) : null;
}
return $results;
}
/**
* Store an item in the cache for a given number of minutes.
*
* @param string $key
* @param mixed $value
* @param float|int $minutes
* @return void
*/
public function put($key, $value, $minutes)
{
$this->connection()->setex(
$this->prefix.$key, (int) max(1, $minutes * 60), $this->serialize($value)
);
}
/**
* Store multiple items in the cache for a given number of minutes.
*
* @param array $values
* @param float|int $minutes
* @return void
*/
public function putMany(array $values, $minutes)
{
$this->connection()->multi();
foreach ($values as $key => $value) {
$this->put($key, $value, $minutes);
}
$this->connection()->exec();
}
/**
* Store an item in the cache if the key doesn't exist.
*
* @param string $key
* @param mixed $value
* @param float|int $minutes
* @return bool
*/
public function add($key, $value, $minutes)
{
$lua = "return redis.call('exists',KEYS[1])<1 and redis.call('setex',KEYS[1],ARGV[2],ARGV[1])";
return (bool) $this->connection()->eval(
$lua, 1, $this->prefix.$key, $this->serialize($value), (int) max(1, $minutes * 60)
);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int
*/
public function increment($key, $value = 1)
{
return $this->connection()->incrby($this->prefix.$key, $value);
}
/**
* Decrement the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int
*/
public function decrement($key, $value = 1)
{
return $this->connection()->decrby($this->prefix.$key, $value);
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value)
{
$this->connection()->set($this->prefix.$key, $this->serialize($value));
}
/**
* Get a lock instance.
*
* @param string $name
* @param int $seconds
* @return \Illuminate\Contracts\Cache\Lock
*/
public function lock($name, $seconds = 0)
{
return new RedisLock($this->connection(), $this->prefix.$name, $seconds);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return bool
*/
public function forget($key)
{
return (bool) $this->connection()->del($this->prefix.$key);
}
/**
* Remove all items from the cache.
*
* @return bool
*/
public function flush()
{
$this->connection()->flushdb();
return true;
}
/**
* Begin executing a new tags operation.
*
* @param array|mixed $names
* @return \Illuminate\Cache\RedisTaggedCache
*/
public function tags($names)
{
return new RedisTaggedCache(
$this, new TagSet($this, is_array($names) ? $names : func_get_args())
);
}
/**
* Get the Redis connection instance.
*
* @return \Predis\ClientInterface
*/
public function connection()
{
return $this->redis->connection($this->connection);
}
/**
* Set the connection name to be used.
*
* @param string $connection
* @return void
*/
public function setConnection($connection)
{
$this->connection = $connection;
}
/**
* Get the Redis database instance.
*
* @return \Illuminate\Contracts\Redis\Factory
*/
public function getRedis()
{
return $this->redis;
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return $this->prefix;
}
/**
* Set the cache key prefix.
*
* @param string $prefix
* @return void
*/
public function setPrefix($prefix)
{
$this->prefix = ! empty($prefix) ? $prefix.':' : '';
}
/**
* Serialize the value.
*
* @param mixed $value
* @return mixed
*/
protected function serialize($value)
{
return is_numeric($value) ? $value : serialize($value);
}
/**
* Unserialize the value.
*
* @param mixed $value
* @return mixed
*/
protected function unserialize($value)
{
return is_numeric($value) ? $value : unserialize($value);
}
}