Skip to content

Instantly share code, notes, and snippets.

@tillkruss
Last active March 4, 2016 05:02
Show Gist options
  • 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;
}
}
@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