Créez votre propre framework… avec les composants Symfony2 (partie 10) | KeiruaProd
Je suis développeur web freelance et propose des formations à Symfony2 ! Contactez-moi pour en discuter.

Cet article est la traduction d’un article original de Fabien Potencier, à l’origine de Symfony2, disponible ici.Créez votre propre framework… avec les composants Symfony2 (partie 10)

Dans la conclusion de la seconde partie de cette série, j’ai parlé d’un des grands avantages de l’utilisation des composants Symfony2 : l’interopérabilité entre les tous framework et les applications qui les utilisent. Faisons un grand pas en avant dans cette direction en faisant implémenter à notre framework HttpKernelInterface :


namespace Symfony\Component\HttpKernel;

interface HttpKernelInterface
{
/**
* @return Response une instance de Response
*/
function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true);
}


HttpKernelInterface est, sans doute le bout de code le plus important du composant HttpKernel (sérieusement). Les framework et applications qui implémentent cette interface sont complètement interopérables. De plus, cela apporte également beaucoup de fonctionnalités intéressantes sans aucun effort.

Mettez à jour votre framework pour qu’il implémente cette interface :


Même si ce changement a l'air trivial, il nous apporte beaucoup ! Parlons d'un des apports les plus impressionnants : le support transparent du cache HTTP.

La classe HttpCache implémente un proxy inverse complet, écrit en PHP; Il implémente HttpKernelInterface et s'articule autour d'une autre instance de HttpKernelInterface :


// example.com/web/front.php

$framework = new Simplex\Framework($dispatcher, $matcher, $resolver);
$framework = new HttpKernel\HttpCache\HttpCache($framework, new HttpKernel\HttpCache\Store(__DIR__.'/../cache'));

$framework->handle($request)->send();

C'est tout ce que cela demande pour ajouter le support du cache HTTP à notre framework. C'est pas fabuleux ?

Configurer le cache doit être fait à travers les headers du cache HTTP. Par exemple, pour mettre en cache une réponse 10 secondes, utilisez la méthode Response::setTtl() :


// example.com/src/Calendar/Controller/LeapYearController.php

public function indexAction(Request $request, $year)
{
$leapyear = new LeapYear();
if ($leapyear->isLeapYear($year)) {
$response = new Response('Oui, c\'est une année bissextile !');
} else {
$response = new Response('Non, ce n\'est pas une année bissextile.');
}

$response->setTtl(10);

return $response;
}

Si, comme moi, vous lancez le framework depuis la ligne de commande en simulant des requêtes ("Request::create('/is_leap_year/2012')"), vous pouvez facilement débugger les instances des réponses en affichant leur contenu sous forme de chaine de caractères ("echo $response;"), car cela affiche tous les headers ainsi que le contenu de la réponse.

Pour nous assurer que cela fonctionne correctement, ajoutez un nombre aléatoire au contenu de la réponse et vérifiez que ce nombre ne change que toutes les 10 secondes :


$response = new Response('Oui, c\' est une année bissextile ! '.rand());

Lorsque vous réalisez le déploiement dans l'environnement de production, continuez d'utiliser le proxy inverse de Symfony2 (très bien pour les hébergements partagés) ou encore mieux, utilisez en un d'encore plus efficace tel que Varnish.

utiliser les headers de cache HTTP pour gérer le cache de notre application est très puissant et vous permet de configurer aux petits oignons votre stratégie de mise en cache, car vous pouvez utiliser à la fois l'expiration et le modèle de validation des spécifications HTTP. Si vous n'êtes pas à l'aise avec ces concepts, je vous recommande fortement de lire le chapitre sur le cache HTTP de la documentation de Symfony2.

La classe de réponse contient plusieurs autres méthodes qui nous permettent de configurer le cache HTTP très facilement. "setCache()" est une des plus puissantes, car elle délègue les stratégies de mise en cache les plus courantes dans un simple tableau :


$date = date_create_from_format('Y-m-d H:i:s', '2005-10-15 10:00:00');

$response->setCache(array(
'public' => true,
'etag' => 'abcde',
'last_modified' => $date,
'max_age' => 10,
's_maxage' => 10,
));

// c'est l'équivalent du code suivant :
$response->setPublic();
$response->setEtag('abcde');
$response->setLastModified($date);
$response->setMaxAge(10);
$response->setSharedMaxAge(10);

Lorsque vous utilisez le modèle de validation, la méthode isNotModified() vous permet de facilement réduire le temps de réponse en court-cicuitant la génération de la réponse dès que possible :


$response->setETag('ce_que_vous_calculez_comme_etag');

if ($response->isNotModified($request)) {
return $response;
}
$response->setContent('Contenu calculé de la réponse');

return $response;

Utiliser le cache HTTP c'est bien, mais que faire si l'on ne peut mettre en cache la page entière ? Et si vous pouviez mettre en cache tout sauf la barre latérale, qui est plus dynamique que le reste du contenu ? Les Edge Side Includes (ESI) peuvent nous venir en aide ! Au lieu de générer le tout le contenu en une fois, les ESI nous permettent de délimiter la région d'une page comme contenu de l'appel à une sous-requête :


Ceci est le contenu de votre page

Est-ce que 2012 est bissextile ?

Autre contenu

Pour que les tags ESI soient supportés dans le HttpCache, vous devez lui fournir une instance de la classe "ESI". La classe ESI extrait automatiquement les tags ESI et réalise les sous-requêtes pour les convertir en contenu approprié :


$framework = new HttpKernel\HttpCache\HttpCache(
$framework,
new HttpKernel\HttpCache\Store(__DIR__.'/../cache'),
new HttpKernel\HttpCache\ESI()
);

Pour que les ESI fonctionne, il vous faut un proxy inverse qui les supporte, comme celui de Symfony2. Varnish est la meilleure alternative et est open-source.

Lorsque l'on utilise des stratégies de mise en cache complexe et/ou beaucoup de tags ESI, il peut être difficile de comprendre pourquoi et quand une ressource doit être mise en cache. Pour faciliter le débuggage, vous pouvez activer le mode de débug :


$framework = new HttpCache($framework, new Store(__DIR__.'/../cache'), new ESI(), array('debug' => true));

Le mode de début ajoute un header X-Symfony-Cache à chaque réponse pour décrire ce que la couche de cache a fait :


X-Symfony-Cache: GET /is_leap_year/2012: stale, invalid, store

X-Symfony-Cache: GET /is_leap_year/2012: fresh

HttpCache supporte de nombreuses autres fonctionnalités d'extensions de contrôle de cache, comme par exemple "stale-while-revalidate" et "stale-if-error" telle qu'elles ont été définies dans la RFC 5861.

Avec l'ajout de cette simple interface, notre framework peut maintenant bénéficier de nombreuses fonctionnalités embarquées dans le composant HttpKernel; La mise en cache HTTP est l'une des plus importante, car elle peut faire décoller les performances de votre application !

Répondre

Unable to load the Are You a Human PlayThru™. Please contact the site owner to report the problem.