[PHP] Mise en cache d'un tableau de données SQL

Pour faire suite à mon billet sur l'optimisation PHP/SQL d'un site web, voici une méthode pour mettre en cache des données issues d'une requête SQL de type SELECT.

Php propose deux fonctions aussi puissantes qu'utiles (mais aussi méconnues) : serialize et unserialize.

  • Serialialize compresse (linéarise) un tableau Php
  • Unserialize le décompresse (ou délinéarise), tout simplement.

A partir de là, l'idée paraît s'imposer d'elle même : pour certaines requêtes qui sont énormément exécutées et/ou qui sont très lourdes (par exemple les données d'un membre utilisées sur toutes les pages d'un site), pourquoi ne pas mettre en cache le tableau issu d'un mysql_fetch_array() ? Ainsi, une fois que la requête a été exécuté on n'accède plus à la base de donnée, on récupère le tableau de données dans un fichier texte puis on le décompresse.

La première fonction permet, tout simplement, d'écrire dans un fichier (en le créant, le cas échéant) :

<?
function maj_fichier($file,$valeur)
{
$fp = fopen("$file","w+"); // ouverture du fichier en écriture (on le créé s'il n'existe pas)
fputs($fp, $valeur); // on écrit dans le fichier
fclose($fp);
}
?>

La seconde - et c'est la fonction qui nous intéresse - est la fonction de mise en cache :

(pour l'utiliser vous aurez besoin de la fonction maj_fichier() ci-dessus et de la fonction requete_sql disponible sur ce billet)

<?
function MiseEnCache($nomFichier,$table,$where,$champs)
{

if(file_exists($nomFichier)) // si les variables sont en cache
{
$requete = unserialize(lire_fichier($nomFichier)); // on utilise le fichier cache (unserialize = decompresser le tableau)
}
else // sinon on fait la requete sql
{
$requete = requete_sql($table, $champs, $where);
maj_fichier($nomFichier, serialize($requete)); // on place le resultat du tableau dans un fichier (serialize = compresser le tableau)
}

return $requete;
}
?>

Exemple d'utilisation :

<?
$req_membre=MiseEnCache("/cache/membres/membre-".$id_membre.".txt","membres", "id='$id_membre'", "prenom,nom,date_inscription,login");

echo"Bienvenue ".$req_membre[prenom]." ".$req_membre[nom]." !";
?>

Cet exemple permet de pouvoir afficher sur toutes les pages le prénom et le nom du membre en effectuant la requête qu'une seule fois ! Malin n'est-ce pas ?

Mais bien sur vous-vous dites : et si le membre modifie son nom, l'information sera erronée ?

La réponse est simple : il suffit de supprimer le fichier texte lors de la modification des informations pour le régénérer avec les bonnes !!

Il y a néanmoins une limitation à l'utilisation de ce procédé : ne l'utilisez pas pour des données sensibles (mot de passe, email, etc.) car un fichier texte est beaucoup plus facilement accessible pour un pirate qu'une base de données...