New in Symfony 3.3: Memcached Cache Adapter

Contributed by
Rob Frawley and Nicolas Grekas
in #20858 and #21108.

The Symfony Cache component includes several adapters to support different caching mechanisms such as Redis, APCu, the filesystem, etc. In Symfony 3.3, we added a new adapter for Memcached.

When using it as a component, create first the connection to the Memcached server and then instantiate the new adapter:

1
2
3
4
use Symfony\Component\Cache\Adapter\MemcachedAdapter;

$client = MemcachedAdapter::createConnection('memcached://localhost');
$cache = new MemcachedAdapter(\Memcached $client, $namespace = '', $defaultLifetime = 0);

In addition to simple servers, the connection can also be a cluster of Memcached instances with all kinds of custom configuration:

1
2
3
4
5
6
7
8
9
$client = MemcachedAdapter::createConnection(array(
    // format => memcached://[user:pass@][ip|host|socket[:port]][?weight=int]
    // 'weight' ranges from 0 to 100 and it's used to prioritize servers
    'memcached://my.server.com:11211'
    'memcached://rmf:abcdef@localhost'
    'memcached://127.0.0.1?weight=50'
    'memcached://username:the-password@/var/run/memcached.sock'
    'memcached:///var/run/memcached.sock?weight=20'
));

When used in a Symfony application, it's even simpler to configure and use Memcached:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# app/config/config_prod.yml
framework:
    cache:
        # defaults to memcached://localhost
        default_memcached_provider: "memcached://my.server.com:11211"
        # ...
        pools:
            app.cache.products:
                adapter: cache.adapter.memcached
                public: true
                # ...

Now you can start storing and fetching items in your Memcached-based cache:

1
2
3
4
5
6
7
8
$cacheProduct = $this->get('app.cache.products')->getItem($productId);
if (!$cacheProduct->isHit()) {
    $product = ...
    $cacheProduct->set($product);
    $this->get('app.cache.products')->save($cacheProduct);
} else {
    $product = $cacheProduct->get();
}

Comments

I'm loving these new improvements, but can we please stop using `$this->get()` in the docs and articles? Using the DI container as a service locator is against the best practices these days and docs should reflect that if we can.
@Amine I'm sorry but we can't do that. For the docs and the blog posts we use a standardized set of practices such as always using a single bundle called AppBundle, always using ACME if a company vendor is needed, always using $this->get() to get services, etc.

Of course this doesn't mean that your comment is wrong, but we decided that the pros of doing this are more than that cons. Thanks for understanding it.
@Javier Thanks for your response, but I have to agree with Amine. People seriously looking for solid frameworks get put off by documentation that encourages bad practices.

We hadn't always used the AppBundle in the past. That was a change we made along the way to improve things. So couldn't we expect to see other improvement to the doc standards in the future?

That said, Symfony docs are still world-class. And I hope they grow with the framework to stay on top.
Agree with @Amine and @Matt. As a beginner I read docs a lot and using (copy-pasting) its code from tutorials. So what is correct way to avoid using $this->get()?
@Sergey The accepted practice is to only inject the services you need, and not the entire container.
@Jelle Kapitein Yes, I agree with 'only inject the services you need', but if the code is in Symfony controller, there is no good way to avoid using $this->get() to get service.
@kiooss @Jelle For avoid using $this->get() in controller in our company we use https://github.com/dunglas/DunglasActionBundle

All pros described in the doc to this bundle.
At the very least, add a note indicating that $this->get() is not a best practice.

Comments are closed.

To ensure that comments stay relevant, they are closed for old posts.