Skip to content

Instantly share code, notes, and snippets.

@tillkruss
Last active March 4, 2016 05:02
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save tillkruss/cf4772c50149162109bb to your computer and use it in GitHub Desktop.
Save tillkruss/cf4772c50149162109bb to your computer and use it in GitHub Desktop.
[Laravel 5.1] Use Redis PECL/HHVM extension

Add App\Providers\RedisServiceProvider::class to 'providers' in config/app.php.

<?php
namespace App\Redis;
use Redis;
use Illuminate\Redis\Database as RedisDatabase;
use Illuminate\Contracts\Redis\Database as DatabaseContract;
class Database extends RedisDatabase implements DatabaseContract
{
protected function createSingleClients(array $servers, array $options = [])
{
$clients = [];
$servers = array_except($servers, ['cluster']);
foreach ($servers as $key => $server) {
$redis = new Redis();
$redis->connect($server['host'], $server['port']);
if (isset($server['password'])) {
$redis->auth($server['password']);
}
$redis->select($server['database']);
$clients[$key] = $redis;
}
return $clients;
}
}
<?php
namespace App\Providers;
use Cache;
use App\Redis\Store;
use App\Redis\Database;
use App\Redis\Repository;
use Illuminate\Support\Arr;
use Illuminate\Cache\CacheManager;
use Illuminate\Redis\RedisServiceProvider as ServiceProvider;
class RedisServiceProvider extends ServiceProvider
{
public function boot()
{
Cache::extend('redis', function ($app, $config) {
$repository = new Repository(
new Store(
$app['redis'],
Arr::get($config, 'prefix') ?: $this->app['config']['cache.prefix'],
Arr::get($config, 'connection', 'default') ?: 'default'
)
);
if ($app->bound('Illuminate\Contracts\Events\Dispatcher')) {
$repository->setEventDispatcher($app['Illuminate\Contracts\Events\Dispatcher']);
}
return $repository;
});
}
public function register()
{
$this->app->singleton('cache.store', function ($app) {
return new Repository($app['cache']->driver()->getStore());
});
$this->app->singleton('cache', function ($app) {
return new CacheManager($app);
});
$this->app->singleton('redis', function ($app) {
return new Database($app['config']['database.redis']);
});
}
}
<?php
namespace App\Redis;
use Illuminate\Cache\Repository as BaseRepository;
class Repository extends BaseRepository
{
public function has($key)
{
$value = $this->get($key);
return ! is_null($value) && $value !== false;
}
public function get($key, $default = null)
{
$value = $this->store->get($key);
if (is_null($value) || $value === false) {
$this->fireCacheEvent('missed', [$key]);
$value = value($default);
} else {
$this->fireCacheEvent('hit', [$key, $value]);
}
return $value;
}
public function add($key, $value, $minutes)
{
if (method_exists($this->store, 'add')) {
return $this->store->add($key, $value, $this->getMinutes($minutes));
}
$currentValue = $this->get($key);
if (is_null($currentValue) || $currentValue === false) {
$this->put($key, $value, $minutes);
return true;
}
return false;
}
public function remember($key, $minutes, Closure $callback)
{
$value = $this->get($key);
if (! is_null($value) && $value !== false) {
return $value;
}
$this->put($key, $value = $callback(), $minutes);
return $value;
}
public function rememberForever($key, Closure $callback)
{
$value = $this->get($key);
if (! is_null($value) && $value !== false) {
return $value;
}
$this->forever($key, $value = $callback());
return $value;
}
}
<?php
namespace App\Redis;
use Illuminate\Cache\TagSet;
use Illuminate\Cache\RedisStore;
class Store extends RedisStore
{
public function tags($names)
{
return new TaggedCache($this, new TagSet($this, is_array($names) ? $names : func_get_args()));
}
}
<?php
namespace App\Redis;
use Illuminate\Cache\RedisTaggedCache;
class TaggedCache extends RedisTaggedCache
{
public function has($key)
{
$value = $this->get($key);
return ! is_null($value) && $value !== false;
}
public function get($key, $default = null)
{
$value = $this->store->get($this->taggedItemKey($key));
return ! is_null($value) && $value !== false ? $value : value($default);
}
public function add($key, $value, $minutes)
{
$currentValue = $this->get($key);
if (is_null($currentValue) || $currentValue === false) {
$this->put($key, $value, $minutes);
return true;
}
return false;
}
public function remember($key, $minutes, Closure $callback)
{
$value = $this->get($key);
if (! is_null($value) && $value !== false) {
return $value;
}
$this->put($key, $value = $callback(), $minutes);
return $value;
}
public function rememberForever($key, Closure $callback)
{
$value = $this->get($key);
if (! is_null($value) && $value !== false) {
return $value;
}
$this->forever($key, $value = $callback());
return $value;
}
}
@it-can
Copy link

it-can commented Sep 13, 2015

Is this only for the Cache system in Laravel? Or does it globally replace the default Redis driver in Laravel? (so all redis calls within Laravel (queue, etc) will use this?)

@tillkruss
Copy link
Author

I've made this into a Laravel 5.2 package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment