18/12/2015 - DOCTRINE, MEMCACHED, SYMFONY
This tutorial is based on DoctrineCacheBundle. Memcached needs to be installed in OS and enabled in php.ini. Example below will show us how to use memcached cache to increase application performance. For more information, you can read doctrine caching chapter, memcached cheat sheet and phpMemcachedAdmin browser GUI.
Add "doctrine/doctrine-cache-bundle" : "1.2.2"
to composer.json and install it. After installation, add new Doctrine\Bundle\DoctrineCacheBundle\DoctrineCacheBundle(),
to AppKernel.php file.
# app/config/config.yml
doctrine_cache:
providers:
inanzzz_memcached_cache:
namespace: INANZZZ
memcached:
servers:
memcached01:
host: 127.0.0.1
port: 11211
services:
application_backend.controller.football:
class: Application\BackendBundle\Controller\FootballController
arguments:
- @templating
- @application_backend.repository.league
- @doctrine.orm.entity_manager
- @doctrine_cache.providers.inanzzz_memcached_cache
services:
application_backend.repository.league:
class: Application\BackendBundle\Repository\LeagueRepository
factory: [@doctrine.orm.entity_manager, getRepository]
arguments: [Application\BackendBundle\Entity\League]
namespace Application\BackendBundle\Controller;
use Application\BackendBundle\Repository\LeagueRepository;
use Doctrine\Common\Cache\MemcachedCache;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
/**
* @Route("football", service="application_backend.controller.football")
*/
class FootballController extends Controller
{
private $templating;
private $leagueRepository;
private $entityManager;
private $memcached;
public function __construct(
EngineInterface $templating,
LeagueRepository $leagueRepository,
EntityManagerInterface $entityManager,
MemcachedCache $memcached
) {
$this->templating = $templating;
$this->leagueRepository = $leagueRepository;
$this->entityManager = $entityManager;
$this->memcached = $memcached;
}
/**
* @Method({"GET"})
* @Route("")
*/
public function indexAction()
{
$cacheId = 'find_all';
if ($this->memcached->contains($cacheId)) {
$result = $this->memcached->fetch($cacheId);
} else {
$result = $this->leagueRepository->findAll();
$this->memcached->save($cacheId, $result, 60);
}
return $this->getTemplate(['result' => $result]);
}
/**
* @param array $parameters
*
* @return Response
*/
private function getTemplate(array $parameters = [])
{
return $this->templating->renderResponse(
'ApplicationBackendBundle:Football:index.html.twig',
$parameters
);
}
}
namespace Application\BackendBundle\Repository;
use Doctrine\ORM\EntityRepository;
class LeagueRepository extends EntityRepository
{
public function findAll()
{
$qb = $this->createQueryBuilder('l')
->select('l, t, p')
->innerJoin('l.team', 't')
->innerJoin('t.player', 'p')
->orderBy('l.name', 'ASC')
->addOrderBy('t.name', 'ASC')
->addOrderBy('p.name', 'ASC')
->getQuery();
$qb = $qb->getResult();
return $qb;
}
}
{% extends '::base.html.twig' %}
{% block body %}
{% spaceless %}
{{ dump(result) }}
{% endspaceless %}
{% endblock %}
Mac:football inanzzz$ telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
# As you can see below, no cache item exists yet
stats items
END
As you can see below, memory %MEM
is not used at all.
Calling http://football.local/app_dev.php/backend/football
. You can use browser based application phpMemcachedAdmin to monitor caching activities.
Millisecond MB
1913 31.5 (*) query run
418 24.2
415 24.2
402 24.2
660 28.8 (*) query run
410 24.2
423 24.2
412 24.2
Mac:football inanzzz$ telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
# As you can see below, new item 28 has been created
stats items
STAT items:28:number 1
STAT items:28:age 83
STAT items:28:evicted 0
STAT items:28:evicted_nonzero 0
STAT items:28:evicted_time 0
STAT items:28:outofmemory 0
STAT items:28:tailrepairs 0
STAT items:28:reclaimed 0
STAT items:28:expired_unfetched 0
STAT items:28:evicted_unfetched 0
STAT items:28:crawler_reclaimed 0
STAT items:28:crawler_items_checked 0
STAT items:28:lrutail_reflocked 0
END
# As you see below, "INANZZZ" is namespace and "find_all" is the cache key.
stats cachedump 28 100
ITEM INANZZZ[find_all][1] [38125 b; 1450458735 s]
END
As you can see below, memory %MEM
is now used.