Le cache des blocks sur Magento
Le cache block sur Magento... Quelle galère !
Enfin... à ce qu'on dit.
Je comprends rien... c'est quoi
cache_tags
?C'est comme
cache_key
?
Je ne suis pas de cet avis en fait. Le cache c'est easy, il suffit juste de savoir où on met les pieds !
Vous me suivez ?
Les bases du cache sur Magento
Avant d'attaquer le cache sur les blocks il vous faut savoir quelques petites choses sur le cache en général sur Magento.
La clé, ou cache_key
Une clé le plus souvent c'est unique ! Bah là, c'est pareil.
Un cache est identifié par sa clé. Un changement minime dans le contenu de votre cache doit faire varier sa clé !
Sauf bien sûr si vous ne souhaitez pas avoir les deux versions.
Par exemple on peut mettre en cache la réponse d'une requête SQL, à condition de faire en sorte que la clé soit liée à l'identifiant dans la clause WHERE
de votre requête !
Sinon c'est la loose... Prenons un exemple bidon :
On peut voir que la clé ne change pas car elle dépend de la variable $_cacheKey
qui ne change pas entre le premier et le second appel à la méthode getCountLessThan
.
Maintenant si on change la valeur de $_cacheKey
à jbh_counter_sql_result_%d
le résultat n'est plus le même !
La clé est donc vraiment importante dans la gestion du cache !
La durée de vie, ou cache_lifetime
Là c'est simple ! On peut décider de donner une durée de vie à notre cache (en secondes).
En gros si notre cache est vieux de plus de cache_lifetime
secondes, alors on le supprime et il est généré à nouveau.
Les valeurs de cache_lifetime
:
null
: pas de cachefalse
: 7200 secondes de cache, soit 2 heures(int)
: nombre de secondes de cache-(int)
: équivaut à pas de cache (date d'expiration du cache dépassée dès la prochaine demande)
Les tags, ou cache_tags
Tagguer un cache... Wait... WHAT?
En toute logique quand on veut vider un cache on indique sa clé et on supprime le cache concerné.
Sauf qu'en pratique... bah c'est franchement la merde. Et c'est là que les tags font leur entrée !
Imaginons plusieurs caches avec chacun une liste de tags :
Maintenant, si on veut vider les caches A
et B
on fait tout simplement :
Par défaut Magento fait en sorte que si un tag match un cache celui-ci soit supprimé. Si vous avez renseigné plusieurs tags à vider, tous les cache concernés par un ou plusieurs de ces tags seront supprimés.
Si vous souhaitez supprimer un cache (sur le cache frontend
, pas le cache backend
) qui match tous les tags renseignés il faut faire :
Ici on a vidé le cache du C
.
Le cache sur les blocks
Par défaut un block n'a pas de cache car la méthode getCacheLifetime
du block Mage_Core_Block_Abstract
retourne null
si aucune data cache_lifetime
n'est renseignée.
La gestion du cache sur les blocks utilise le fait que chaque block est un Varien_Object
pour stocker les valeurs de cache_key
, cache_lifetime
et cache_tags
.
Sauf que qui dit Varien_Object
dit __call
... non ?
Donc en fait les variables du cache sont récupérées de la manière suivante :
Donc ? Bah donc on peut surcharger sur nos blocks. Et oui !
La clé avec getCacheKey()
Comme on le sait la clé doit être unique et dépendre du contexte. On a donc plusieurs paramètres à prendre en compte :
- Le store (donc la locale en passant)
- Le design (package & thème)
- Le template
phtml
utilisé - Le nom du block dans le Layout
- Un identifiant (identifiant d'un produit par exemple)
On peut bien sûr ajouter des paramètres dans notre clé.
Bon, mais en gros, quand on a un tableau de paramètres et qu'on veut une chaîne de caractères on fait comment ? implode
? Avec un hash ?
Soyons fous !
Mais en fait... Magento le fait pour nous ; avec l'appel à getCacheKeyInfo()
dans getCacheKey()
:
Si on y regarde de plus près on remarque que la méthode getCacheKeyInfo()
retourne un tableau qui contient une seule valeur : le nom du block dans le Layout :
Dans notre block, on surcharge cette méthode !
Les tags avec getCacheTags()
Par défaut on essaiera toujours de donner une constante CACHE_TAG
à un modèle concocté par nos soins par exemple. A nous de ne pas oublier de l'utiliser !
L'intérêt de définir une constante CACHE_TAG
à nos modèles qui sont utilisés dans nos blocks c'est de pouvoir vider le cache de tous les blocks concernés par nos objets lorsqu'on les sauvegarde par exemple !
Il suffit de modifier la méthode _afterSave
de nos modèles pour y ajouter le clean du cache !
Revenons à nos moutons et voyons à quoi ressemble la méthode getCacheTags
par défaut de Magento :
Allez, on surcharge dans notre block !
J'ajoute ici un exemple vite fait d'un modèle avec une constante CACHE_TAG
bien utilisée :
Vous noterez qu'on peut ajouter n'importe quels tags. Attention cependant à ne pas oublier les tags par défaut récupérés grâce au parent
!
La durée de vie avec getCacheLifetime()
Rien de plus simple !
Pensez à vider le cache !
Utilisez bien les tags enregistrés avec le cache de vos blocks pour vider tout ça !
Vous pouvez aussi enregistrer tous les tags utilisés sur les blocks par défaut d'une page de cette manière :
Dans le fichier /app/code/core/Mage/Core/Model/App.php
, ajoutez un log dans la méthode saveCache
:
Vous aurez ici les tags utilisés ! Mais pas ceux qui ne sont pas utilisés, mais vidés !
Dans le fichier /app/code/core/Mage/Core/Model/App.php
, ajoutez un log dans la méthode cleanCache
:
Conclusion
Gérer le cache des blocks n'est pas une mince affaire mais on s'y retrouve !
Il faut juste savoir s'y prendre.
Vous pouvez également utiliser la méthode addData
dans la surcharge du constructeur secondaire protected function _construct()
de votre block pour y assigner les valeurs de cache_key
, cache_tags
et cache_lifetime
mais je le déconseille.
Bon cache !