Laravel use Memcache instead of MemcacheD - developed.be

Laravel works out of the box with Memcached. However there’s a difference between the linux programs Memcached and Memcache (without the D). To get Laravel to work with Memcache you can write a package yourself.

First of all: don’t edit the original files of the Laravel package. I know you can just find/replace every instance of Memcached and replace it by Memcache, but as soon as you’ll update your project, every change you’ve made to the core files will be overridden and lost. That’s why you have to create a separate package that adds functionality to the system instead of blindly editing the system.

Create a package Memcache

The following command will  create a package in the project/workbench directory. (the vendor directory is only for packages of third party authors). All the packages in the workbench directory will be automatically loaded by Laravel.

php artisan workbench robin_b/extendedCacheProvider

(robin_b is the authors name. You could change that to your name)

Navigate to /workbench/robinb/extended-cache-provider/src/RobinB/ExtendedCacheProvider

Wow, that’s a whole lotta directories. The src directory is where you’d normally put your files as if it were an empty project. That’s why you have to create the same directories again in the src folder (RobinB/ExtendedCacheProvider). These directory names must match your namespace.

Facade

Start with creating a Facade. A facade is used as a static shorthand to connect to a class.

Create a class named “Cache” in the Facades directory that extends from Illuminate\Support\Facades\Facade (=> A facade should always extend from that class).

You only need one function in the class, namely getFacadeAccessor. That functions returns just a string, in this case: “extendedcache“.

Service Provider

As with every package you should also create one or more ServiceProviders. A ServiceProvider tells Laravel what your package can do. It kinda hooks in the Laravel system.

The service provider needs a function named register(). This function returns a new class we call a Manager.

    public function register()
    {
        $this->app['extentedcache'] = $this->app->share(function($app)
        {
            return new ExtendedCacheManager($app); //this is supposed to override the CacheManager
        });
 
        $this->app['memcache.connector'] = $this->app->share(function()
        {
            return new MemcacheConnector;
        });

In the second line you can see “extendedcache”, this is the same string as we used in the Facade. If these strings don’t match, it won’t work, because the Facade looks for that string in the app-array.

The MemcacheConnector is a class we need later in this tutorial.

ExtendedCacheManager

The “ExtendedCacheManager” is a class we have to create next. The class extends from the original \Illuminate\Cache\CacheManager. Take a look at that class and you’ll see there’s a Driver function for each cache mechanism (database, memchached, etc).

In our ExtendedCacheManager we have to create a driver for Memcache named “createMemcacheDriver()“. We can simply copy the original “createMemcachedDriver()” code and find/replace “Memcached” by “Memcache” (except the reference to the app-config).

    protected function createMemcacheDriver()
    {
        $servers = $this->app['config']['cache.memcached']; //we want to use the same connnector setting as memcached.
 
        $memcache = $this->app['memcache.connector']->connect($servers);
 
        return $this->repository(new MemcacheStore($memcache, $this->getPrefix()));
    }

MemcacheConnector

In the ServiceProvider and the ExtendedCacheManager we both reference to a class named “MemcacheConnector”. This class only purpose is connect to Memcache. We can copy the original \Illuminate\Cache\MemcachedConnector and find/replace every “Memcached” string by “Memcache“. Especially the latest function getMemcache() is important because that’s where we return a PHP Memcache object.

    protected function getMemcache()
    {
        return new Memcache;
    }

MemcacheStore

MemcacheStore is where the magic happens. This class puts and gets objects from the Memcache memory. Laravel uses the same functions (get, put, increment,…) for every cache mechanism, that’s why the function names and the Memcache call names can be different. (eg: function put() does a Memcache->set())

We can again copy the code from the original Illuminate\Cache\MemcachedStore and find/replace “Memcached” by “Memcache“.

However, some API-calls to Memcache are different than to Memcached.

function put() should be changed to this:

$this->memcache->set($this->prefix.$key, $value, 0, $minutes * 60);

And get() must be without the value() call, because value() doesn’t exist in Memcache.

config/app.php

Finally we have to alter some settings in app.php

We have to remove the reference to ‘Illuminate\Cache\CacheServiceProvider’,

And add the reference to ‘RobinB\ExtendedCacheProvider\MemcacheServiceProvider’

And in aliases, we have to edit the regular cache facade to our cache facade:

'Cache'           => 'RobinB\ExtendedCacheProvider\Facades\Cache',

Finally do a:

php artisan dump-autoload

This will created extra files in the Workbench

When you want to use the Cache::get() function, use reference:

use RobinB\ExtendedCacheProvider\Facades\Cache;

Sourcecode

You can download the tar.gz file of this tutorial.


Rss Comments

3 comments

  1. Hey thanks for this! Have you tried it on Laravel 4.1? Also I had another workbench already before following this article and when I try to use my Cache::get() from my main app controlled .. I get an error that originates from one of my workbench??

    ReflectionException
    Class memcached.connector does not exist

    workbench\my\benchapp\vendor\illuminate\container\Illuminate\Container\Container.php

    $reflector = new ReflectionClass($concrete);

    Any idea?

    #1 Bob
  2. Go to app/config/cache.php and change driver name as ‘memcache’ instead of ‘memcached’

    #2 Smita
  3. in config/cache.php use driver as memcache

    #3 Smita

Leave a comment