Chapitre: Utiliser le cache
« les objets globaux utiles | ^ Développement avancé | Créer des scripts d'installation automatiques » |
− Table des matières
Mettre en cache des données ou des portions de page HTML générées permet d'améliorer les performances du site web, voir même d'éviter de transférer des données au niveau navigateur.
Jelix propose plusieurs système de cache. Vous avez probablement vu la mise en cache des zones. Vous allez voir ici la mise en cache de données quelconques, et l'utilisation du cache HTTP.
jCache ¶
jCache est une classe permettant de stocker des données dans un système de cache. Le système repose sur des pilotes pour les accès aux données. Il est donc possible d’utiliser memcache, ou encore une base de données voir même le système de fichier. Et vous pouvez développer votre propre pilote.
Configuration ¶
Pour utiliser jCache, il faut d'abord spécifier les paramètres de configuration
du système dans le fichier profiles.ini.php
situé dans var/config/
.
Voir le chapitre sur l'utilisation de ce fichier profiles.ini.php.
Vous pouvez définir plusieurs configurations du système, que l'on nomme “profils”. Ainsi vous pouvez définir des configurations pour le site de production, le site de développement par exemple.
Le type de connexion à indiquer dans les noms des sections de
profiles.ini.php
est jcache
.
Chaque profil doit indiquer au moins ces trois paramètres :
driver
: indique le pilote à utiliser.enabled
: permet d'indiquer si le cache pour ce profil est actif (1) ou non (0). Utile en développement ou débuggage.ttl
: indique le temps d’expiration des données (0 signifie n’expire jamais). Vous pouvez indiquer une durée en secondes, un timestamp UNIX ou encore une date textuelle au format US.automatic_cleaning_factor
: indice de nettoyage automatique du système de cache.
Un profil peut contenir d'autres paramètres, en fonction du pilote utilisé.
Voici un exemple dans le fichier profiles.ini.php
:
[jcache]
default = foo
[jcache:foo]
enabled = 1
driver = file
; autres paramètres...
Pilote memcache ¶
Il utilise l'API memcache de PHP (et non pas memcached).
Paramètres possibles :
driver=memcache
servers
: liste de serveurs memcached.
[jcache:mymemcache]
driver=memcache
ttl=360
enabled=1
servers = memcache_host1:11211,memcache_host2:11211,memcache_host3:11211
Pilote file ¶
Le cache est stocké dans des fichiers.
Paramètres possibles :
driver=file
cache_dir
: le répertoire où les données sont stockées.file_locking
: indique s’il y a verrouillage des fichiers (1) ou non (0).directory_level
: niveau d’arborescence des répertoires du système de cache.directory_umask
: attributs utilisés pour les répertoires.file_name_prefix
: préfixe des noms de fichiers du système de cache.cache_file_umask
: attributs utilisés pour les fichiers.
Pilote db ¶
Ce pilote utilise une table SQL pour stocker les valeurs de cache.
L'installateur de jelix crée la table nécessaire quand l'application l'utilise.
Cependant, pendant le developpement, vous devez vous même créer la table.
Utilisez l'un des scripts SQL dans
lib/jelix/core-modules/jelix/install/sql/install_jcache.schema.*
pour
créer la table.
Paramètres possibles :
driver=db
: la valeur est "db".dao
: un sélecteur vers le fichier dao que vous voulez utiliser. Par défaut, "jelix~jcache".dbprofile
: profil de connexion jDb à utiliser .
Utilisation ¶
jCache
est la classe principale du système de cache. Toutes ses méthodes
sont statiques. Elle effectue un bon nombre d’opérations comme stockage,
suppression, récupération de données. Vous appellerez ces méthodes quand bon
vous semble.
jCache::get($key)
: Pour récupérer une valeur.jCache::set($key, $value, $ttl)
: pour stocker ou modifier une valeur. $ttl est optionneljCache::delete($key)
: pour effacer une valeurjCache::increment($key)
: incremente une valeur (N.B. : la valeur est réduite à sa partie entière - si elle a une partie décimale - puis incrémentée)jCache::decrement($key)
: decremente une valeur (N.B. : la valeur est réduite à sa partie entière - si elle a une partie décimale - puis décrémentée)jCache::add($key, $value)
: pour stocker une nouvelle valeur. Retourne false si la clé existe déjàjCache::replace($key,$value, $ttl)
: pour changer une valeur d'une clé existante. Retourne false si la clé n'existe pas. $ttl est optionnel.jCache::garbage()
: efface toutes les valeurs expiréesjCache::flush()
: efface tout le cache.jCache::call($fn, $fnargs, $ttl)
: utilise le nom et les arguments de la fonction donnée comme clé de la valeur que retourne la fonction. Si la clé existe déjà, renvoi la valeur du cache, sinon appelle la fonction et stocke la valeur retournée dans le cache.
Toutes ces méthodes statiques acceptent un nom de profile jcache en dernier argument.
jResponse et le cache HTTP ¶
Le protocole HTTP possède des en-têtes pour informer le navigateur comment stocker la page qu'on lui envoi, c'est à dire si le navigateur peut la mettre en cache ou pas. Et le navigateur peut, lors d'une requête, indiquer au serveur qu'il a ou pas la page demandée dans son cache, et depuis quand. Coté serveur, on peut donc savoir si le contenu demandé est dans le cache du navigateur, et si il est périmé ou pas, ce qui permet de générer ou pas le contenu.
Jelix 1.4 intègre des nouvelles méthodes dans la classe jResponse
afin de gérer facilement le cache HTTP d’une réponse en exploitant les entête
prévus à cet effet dans le protocole HTTP.
Ces méthodes sont disponibles dans toutes les réponses pour lesquelles l'utilisation du cache HTTP a du sens. N’oubliez pas que ce cache se situe côté client, dans le navigateur de l’utilisateur et non sur le serveur.
Il y a deux façons de gérer le cache coté navigateur : le cache par expiration, et le cache par validation.
Attention : en général, sauf à utiliser la méthode setLifeTime
avec un
cache privé, la mise en cache ne doit pas concerner des pages "personnalisées"
incluant par exemple des données relatifs à l'utilisateur. En effet, le contenu
est succeptible d'être mis en cache par des proxys. Ceux-ci utilisent les
en-têtes de cache envoyés par le serveur pour stocker en cache (ou pas), mais
n'utilisent pas les cookies (notamment ceux de sessions) comme paramètres
discriminants : ils ne mémorisent donc qu'une seule "version" d'une page et tout
les utilisateurs obtiendront cette version de page. Si elle contient des données
personnelles, cela peut avoir des conséquences dramatiques.
Cache par expiration ¶
Le cache par expiration est un cache qui restera valide jusqu'à une certaine
date. Avant cette date, le navigateur ne fera pas de demande au serveur, et
affichera directement la page qu'il a en cache. Par contre, au delà de cette
date, le navigateur redemandera la page au serveur. Vous pouvez spécifier cette
date d'expiration soit en indiquant la date proprement dite (méthode
setExpires
), soit en indiquant une durée (méthode setLifeTime
).
setExpires ¶
La méthode setExpires
permet de spécifier une date jusqu'à laquelle la ressource
sera considérée valide et gardée en cache. En interne, cette méthode ajoute un
entête HTTP “Expires”. Dans le contrôleur :
$rep->setExpires($date);
//ou bien
$rep->setExpires(“+1 days”);
Le paramètre attendu par setExpires
est une date de la forme
jDateTime
, DateTime
ou une chaine compatible avec la fonction
strtotime
.
setLifeTime ¶
La méthode setLifeTime
permet de spécifier un temps (en secondes) pendant lequel
la ressource sera considérée valide et gardée en cache.
Vous avez également la possibilité de spécifier si la ressource peut être mise en cache par n’importe quel cache ou si elle doit être privée et ne pas être mise en cache par des proxys (par défaut : privée).
En interne, cette méthode ajoute un entête HTTP “Cache-Control”.
Dans le contrôleur :
$rep->setLifeTime(3600); //1 heure en cache privé
//ou bien
$rep->setLifeTime(600, true);// 10 minutes en cache partagé
Cache par validation ¶
Le cache par validation permet d'utiliser une politique de mise en cache plus complexe : le navigateur demande systèmatiquement la page au serveur, en lui indiquant une information de validité que lui avait donné le serveur. Mais le serveur, en fonction de cette date, peut décider de renvoyer une nouvelle page, ou de dire au navigateur d'utiliser celle qu'il a en cache.
C'est donc à vous, dans votre contrôleur, de décider si il faut renvoyer ou non
un nouveau contenu. Pour cela, vous indiquez explicitement à la méthode
isValidCache
, soit la dernière date à laquelle la ressource a été modifiée
("Last-Modified"), soit un token correspondant à l'etat de la ressource
("Etag"). À vous donc de récupérer cette date (par exemple, si c'est une page
d'un article, la date de modification de cet article), ou de calculer le token
(qui peut être un checksum md5 par exemple, ou une chaine identifiant de façon unique
la version de la page..).
La méthode isValidCache
, retournera true
si la ressource du navigateur est encore bonne,
ou false
si il faut regénérer la page.
Dans le contrôleur :
$dateLastModified = $foo->updated_at; //date de dernière modification de ma ressource
if ($rep->isValidCache($dateLastModified)) {
// le cache est bon, on arrête là
return $rep;
}
//Ou bien en utilisant “Etag”;
$etag = ... ; //je génère un etag correspondant à l’etat de ma ressource
if ($rep->isValidCache(null, $etag)) {
return $rep;
}
Le paramètre date attendu par isValidCache
est une date de la forme :
jDateTime
, DateTime
ou une chaine compatible avec la fonction
strtotime
.