Lorsqu’une page web PHP génère plusieurs requêtes SQL ou lorsque celle-ci traite beaucoup de données et effectue beaucoup de calculs, il est parfois préférable mettre le résultat en cache pour améliorer la performance du site et économiser les ressources du serveur.
Dans ce tutoriel, nous verrons comment stocker le contenu d’une page PHP dans une base de données afin de renvoyer le contenu plus rapidement au fureteur web des visiteurs.
La page web PHP à mettre en cache
Pour ce tutoriel, nous utiliserons la page web suivante:
<html>
<head>
<title>Ma page web</title>
</head>
<body>
<ol>
<?php
for($i=1;$i<11;$i++)
{
echo "\n<li>item $i</li>";
}
?>
</ol>
</body></html>
Les lignes 7 à 12 sont celles dont nous souhaitons mettre le résultat en cache afin d’éviter que la routine PHP soit exécutée chaque fois que la page est invoquée. Bon évidemment, ce n’est pas le type de routine PHP qui exige beaucoup de ressources mais c’est simplement un exemple…
La table MySQL
Afin de stocker les pages à mettre en cache, nous utiliserons une base de données MySQL avec une table ainsi définie:
- cache_id: entier, clé primaire, auto-incrémenté
- cache_item: varchar(30)
- cache_content: mediumtext
- cache_date: datetime
CREATE TABLE `cache` (`cache_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,`cache_item` VARCHAR( 30 ) NOT NULL ,`cache_content` MEDIUMTEXT NOT NULL ,`cache_date` DATETIME NOT NULL ,UNIQUE (`cache_item`)) ENGINE = MYISAM ;
Activer le « Output Buffering »
En activant ce qu’on appele le « output buffering », le résultat des commandes PHP n’est pas envoyé au fureteur au fur et à mesure qu’elles sont exécutées. Le résultat est plutôt stocké dans une variable à l’aide de la fonction ob_start(). Le résultat de la routine PHP ne sera envoyé au fureteur que lorsque la commande ob_end_flush() sera invoquée.
<html>
<head>
<title>Ma page web</title>
</head>
<body>
<ol>
<?php
ob_start();
for($i=1;$i<11;$i++)
{
echo "\n<li>item $i</li>";
}
ob_end_flush();
?>
</ol>
</body></html>
Mettre en cache le contenu du buffer PHP
Il est possible de récupérer le contenu du buffer PHP à l’aide de la fonction ob_get_contents(). Nous utiliserons donc cette commande pour lire le contenu du buffer et l’insérer dans la table MySQL.
Pour cette partie du tutoriel, nous allons assumer l’existance d’un script PHP (dbconnect.php) effectuant la connexion à la base de données MySQL puisque ce n’est pas l’objectif.
<html>
<head>
<title>Ma page web</title>
</head>
<body>
<ol>
<?php
require_once("dbconnect.php");
ob_start();
for($i=1;$i<11;$i++)
{
echo "\n<li>item $i</li>";
}
$buffer = ob_get_contents();
CacheContent('homepage', $buffer);
ob_end_flush();
function CacheContent($cache_item, $cache_content)
{
$cache_item = addslashes($cache_item);
$cache_content = addslashes($cache_content);
$sql = "delete from cache where cache_item = '$cache_item' limit 1;";
$res = mysql_query($sql);
$sql = "insert into cache (cache_item, cache_content, cache_date) values ('$cache_item', '$cache_content', now());";
$res = mysql_query($sql);
}
?>
</ol>
</body></html>
Nous avons donc ajouté une fonction (CacheContent) qui permet de supprimer toute instance précédente de l’item en cache et d’y insérer la plus récente version du contenu.
Lire le contenu de la cache
Il ne reste maintenant plus qu’à vérifier la page se trouve déjà en cache avant d’exécuter le code PHP. Nous allons ajouter une fonction « GetCacheContent » à cet effet:
<html>
<head>
<title>Ma page web</title>
</head>
<body>
<ol>
<?php
require_once("dbconnect.php");
$cache_content = GetCacheContent('homepage');
if($cache_content)
echo $cache_content;
else
{
ob_start();
for($i=1;$i<11;$i++)
{
echo "\n<li>item $i</li>";
}
$buffer = ob_get_contents();
CacheContent('homepage', $buffer);
ob_end_flush();
}
function CacheContent($cache_item, $cache_content)
{
$cache_item = addslashes($cache_item);
$cache_content = addslashes($cache_content);
$sql = "delete from cache where cache_item = '$cache_item' limit 1;";
$res = mysql_query($sql);
$sql = "insert into cache (cache_item, cache_content, cache_date) values ('$cache_item', '$cache_content', now());";
$res = mysql_query($sql);
}
function GetCacheContent($cache_item)
{
$cache_item = addslashes($cache_item);
$sql = "select cache_content from cache where cache_item = '$cache_item';";
$res = mysql_query($sql);
if(mysql_num_rows($res) > 0)
return(false);
else
return(mysql_result($res, 0, 'cache_content'));
}
?>
</ol>
</body></html>
Évidemment, le tout n’est pas très élégant codé ainsi. Il serait donc plus efficace de mettre toutes les fonctions dans un fichier PHP et d’inclure celui-ci dans chaque page.
À ce stade-ci, il ne reste qu’à définir un processus de nettoyage de la cache qui serait lancé périodiquement à l’aide du service Cron.

