begin process at 2012 02 04 23:32:36
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Class et Objet ( POO )

 > [POO]SYSTÈME DE CACHE

[POO]SYSTÈME DE CACHE


 Information sur la source

Note :
Aucune note
Catégorie :Class et Objet ( POO ) Classé sous :cache, poo, classe cache, class cache, systeme cache Niveau :Débutant Date de création :06/12/2009 Date de mise à jour :28/12/2009 12:43:23 Vu / téléchargé :2 490 / 101

Auteur : destinyfr

Ecrire un message privé
Commentaire sur cette source (7)
Ajouter un commentaire et/ou une note

 Description

Bonjour à tous et à toutes !

Suite à plusieurs remarques dans les commentaires (les 6 premiers ne sont du coup plus valables :D), j'ai refais ma classe de cache.
Quels sont les modifiations ? La gestion de plusieurs fichiers cache dans une même page (pour pouvoir mettre en cache seulement certaines parties de la page ou tout si l'on à envie :p). Stockage du code html de la page et non des requêtes. La possibilité de mettre à jour le cache via un temps de validité ou dynamiquement (à chaque nouvel article par exemple).

Ce qui reste à faire : Pouvoir supprimer tout le dossier cache et non un seul fichier. Régénérer le cache après 1000 chargement de celui-ci par exemple ^^ (enfin si j'en vois l'utilité xD).

Encore une fois, ce n'est qu'un façon de faire un système de cache, je ne prétend pas que celui-ci est le meilleur !

Les fichiers sont stockés sous le format .cache
Pour paramétrer les chemins d'accès au cache etc.. il faut faire comme ceci : chemin.vers.le.cache.fichier

Source

  • <?php
  • include_once('cache.interface.php');
  • include_once('cache.class.php');
  • $cache1 = cache::getInstance('cache1');
  • if(!$cache1->check('cache.test')) {
  • $cache1->start();
  • ?>
  • <html>
  • <head><title>Ohhhh :D i'm a test :p</title></head>
  • <body>
  • <p>Je suis une phrase de test !!!!!!!!!!!!!!<br />
  • Yeah :p</p>
  • </body>
  • </html>
  • <?php
  • $cache1->end();
  • $cache1->add('cache.test');
  • echo $cache1->load('cache.test');
  • }
  • else {
  • echo $cache1->load('cache.test');
  • }
  • ?>
<?php
include_once('cache.interface.php');
include_once('cache.class.php');

$cache1 = cache::getInstance('cache1');

if(!$cache1->check('cache.test')) {
	$cache1->start();
?>
<html>
<head><title>Ohhhh :D i'm a test :p</title></head>
<body>
<p>Je suis une phrase de test !!!!!!!!!!!!!!<br />
Yeah :p</p>
</body>
</html>
<?php
	$cache1->end();
	$cache1->add('cache.test');
	echo $cache1->load('cache.test');
}
else {
	echo $cache1->load('cache.test');
}
?>

 Conclusion

Bref l'utilisation n'est pas très dur, vous ne devriez donc pas avoir trop de difficultés à l'utiliser xD (au pire, suivez l'exemple).

Voilà, bonne journée et bonnes fêtes de fin d'année.

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Historique

06 décembre 2009 18:58:03 :
Remplacement d'une fonction par un autre.
28 décembre 2009 12:43:24 :
Refonte complet du code. Les 6 derniers commentaires ne sont plus valable pour cette version.

 Sources du même auteur

Source avec Zip [POO][PHP5]UN SITE MULTILANGUE VIA XML
[CMS - POO - PDO]MY GESTION BIENTÔT DISPONIBLE.

 Sources de la même categorie

CLASSE DE GESTION DE "VARIABLES GLOBALES D'ENVIRONNEMENT" par pifou25
Source avec Zip COLLECTION.CLASS.MIN.PHP par thunderhunter
Source avec Zip SIMPLETEMPLATE par thunderhunter
Source avec Zip Source avec une capture VOIR QUI VISITE VOTRE SITE par Dariumis
Source avec Zip CLASS SIMPLE CBASEDONNEE par smag42

 Sources en rapport avec celle ci

CLASSE DE GESTION DE "VARIABLES GLOBALES D'ENVIRONNEMENT" par pifou25
Source avec Zip Source avec une capture TODO LIST (AJAX/PHP5) par VinceMonkeyz
Source avec Zip CLIENT / SERVEUR : LES SOCKETS par Morphinof
Source avec Zip SERCACHE2 > CACHE DE PAGES, D'OBJETS, DE REQUÊTES ... (NON T... par Astalavista
Source avec Zip [PHP5]CLASSE DE TEMPLATE PHP AVEC CACHE par hametsu21

Commentaires et avis

Commentaire de neigedhiver le 07/12/2009 17:06:16

Salut,

Ce que tu mets en cache, ce n'est pas un objet, mais un tableau. Et un tableau n'est pas un objet, en php : c'est un tableau.

Pour que les fonctionnalités soient toutes présentes, il manque une fonction delete().

Ta méthodes read() n'intéragit pas correctement avec la méthode __get() : elle ne devrait pas retourner le contenu du fichier, mais plutôt un booléen en cas de succès. Le contenu du fichier devrait alors être automatiquement stocké dans une propriété pour être réutilisé plus tard par __get(). Tel que ça fonctionne actuellement, si le fichier existe et n'est pas accessible en lecture, tu te retrouves avec une erreur.
La méthode __get() n'est pas vraiment optimisée... Tu exécutes 2 fois unserialize() sur une variable dont tu ignores la taille. Par ailleurs, aucune vérification si ce n'est la nature du résultat (array ou non)
Pour bien faire, il faudrait donc que :
- la méthode read() vérifie, avant de le lire, que le fichier existe ET EST ACCESSIBLE EN LECTURE (parce que ça peut ne pas être le cas, et si le fichier ne peut pas être lu, tu te retrouves avec une erreur => autant anticiper)
- la méthode read() stocke le contenu du fichier dans une propriété et renvoie TRUE en cas de succès, FALSE sinon
- la méthode __get() retourne TOUJOURS quelque chose SANS ERREUR. Si le contenu du fichier est utilisable, alors elle le renvoit délinéarisé. Sinon, il faut qu'elle renvoit autre chose. En l'état actuel, elle repose sur le postulat que la méthode read() renverra TOUJOURS un résultat exploitable... Ce qui peut s'avérer faux et causer... un bug.

Enfin, ton exemple est un mauvais exemple. Il illustre certes le fonctionnement de la classe et ses méthodes, mais il est déplorable en terme de performances.
Tu utilises PDO, c'est très louable. Rien que pour ça, je te remercie du fond du coeur. Mais utiliser fetAll(), écrire le résultat SYSTÉMATIQUEMENT dans un fichier puis itérer dessus n'a pas de sens. Par ailleurs, préparer une requête dans laquelle il n'y a aucun paramètre est une perte de performances : autant utiliser PDO::query() directement.
La classe PDOStatement implémente l'interface Traversable ce qui la rend utilisable directement dans une boucle foreach(). L'utilité d'un itérateur est, rappelons-le, de ne parcourir un objet qu'une seule fois.

Enfin, il manque la gestion du temps : un cache sans durée de vie n'a pas de sens. Il est indispensable de savoir quand le fichier de cache doit être régénéré. Il ne doit pas l'être systématiquement (sinon il ne sert à rien), mais il doit quand même l'être de temps en temps (à déterminer par l'utilisateur, pour chaque fichier ou pour toutes les instances, ça, c'est toi qui voies) sinon les données seront obsolètes...
Ton exemple devrait donc montrer comment vérifier si les données sont présentes en cache, comment utiliser le cache s'il existe pour un résultat donné, comment le réécrire s'il n'existe pas ou s'il est obsolète, etc.
Il faut aussi penser à un système de purge, type garbage collector, pour supprimer les fichiers de caches périmés (de manière plus ou moins automatique, mais une méthode spécifique devrait permettre ça facilement).

Un défaut de ton système est que le nom du fichier est déterminé d'après le md5 du contenu : cela signifie qu'il faut obligatoirement exécuter la requête pour ensuite vérifier si le résultat est en cache ou non. Or tout l'intérêt d'un fichier cache est de NE PAS avoir à exécuter la requête si son résultat existe déjà... Il est donc préférable de laisser l'utilisateur choisir le nom de son cache (il est grand quand même, il est censé savoir développer en PHP et gérer correctement ses variables) et lui faire confiance (ou pas : d'où la nécessité de toutes les vérifications que tu omets).

Voilà voilà... ^^

Commentaire de destinyfr le 07/12/2009 22:23:52

Salut,

Merci pour le commentaire ^^
Il est vrai que le cache est simple (en même temps j'ai pas dit que c'était le meilleur cache du monde :D). Pour ce qui est de la vérification sur le temps des fichiers, je n'en voyais pas l'utilité car ma conception d'un cache est un peut différente. Pour le problème entre la fonction read et __get, c'est très largement améliorable, en effet et j'aurais du y penser bien avant (gros erreur de ma part). Pour la méthode delete, j'y avais pensé, et elle était présente (au départ), mais ayant une conception de ce qu'est un cache, je n'en voyais pas ici l'utilité (car étant donnée que si aucun article est mis à jour, le cache n'as pas forcément besoin de changer).

Bref c'est une version basique et très peu complète d'un cache, c'est vrai. Je le modifie dès que possible (surement à partir de demain soir) et je posterai un mise à jour dès que possible.

Pour ce qui est de l'array, c'est du faite de l'utilisation de fetchAll. Je vais remédier par la même occasion à ce problème.

Merci encore pour ton commentaire, je vais prendre en compte ce que tu viens de dire et modifier tout ça.

Merci !

Commentaire de neigedhiver le 07/12/2009 22:31:09

Plop,

Je crois que je vois à peu près pourquoi t'as pas de gestion du temps : le cache est mis à jour quand tu postes un nouvel article, c'est ça ? Dans ce cas, pas besoin de le regénérer à intervalles réguliers.
Du coup, je ne comprends pas pourquoi tu choisis de mettre un résultat de requête plutôt que du html... Dans ce cas précis, ce n'est pas pertinent : autant avoir du html pré-digéré prêt à afficher plutôt que des données qu'il faudra de toute façon traiter, toujours de la même façon... Il me paraît préférable de traîter les données une bonne fois pour toute.
Je ne dis pas par là que ton cache est inutile, juste que dans le contexte que j'imagine (une liste d'articles sur une page d'accueil par exemple), ce n'est pas justifié de faire un tel cache plutôt que de mettre en cache du html.
Tu as peut-être des arguments en faveur de ton implémentation, je suis curieux de les avoir pour confronter nos points de vue (de manière constructive, hein, donc).

Commentaire de destinyfr le 07/12/2009 23:55:39

Salut,

Comme tu l'as très bien dit, le cache est mis à jour lorsqu'un nouvel article (ou bien topic sur un forum, un commentaire etc.. bref ce que tu veux) est posté (d'où l'inutilité de vérifier la validité du fichier cache car il sera régénéré).
Je préfère mettre en cache un retour de requête plutôt que du html car dans mes codes, je dispose de plusieurs templates. Il est vrai que j'aurai pu mettre en cache le html (et pour vérifier que le cache soit à jour après un nouvel article, vider celui-ci, ce qui aurait obligé un rechargement du cache sur l'index => ce n'est qu'une façon comme une autre !) mais cela m'aurait obligé à créer un fichier cache par template (je parle pour une page index avec des news uniquement).
Or via cette méthode de cache, je peux avoir un fichier cache global, c'est à dire le même quelque soit le template utilisé.
Je pense surtout que c'est la raison principal pour laquelle je stock un retour requête.

Ce type de cache peut (je pense) être utile lorsqu'il y à différentes requêtes sur une page et dont les mises à jours varient. Je vais prendre l'exemple d'un compteur de visite sur une page de news. Le compteur de visite à pour obligation d'enregistrer 1 seul et unique fois un visiteur ayant la même IP, les news elles sont mises à jour que lors qu'il y à un nouvel article d'ajouté sur le site.

Comme tu auras surement compris, le compteur de visite sera mis à jour bien plus souvent que les news. Le fait de stocker des requêtes dans des fichiers et non tout le code html dans 1 fichier, permet de mettre à jour une seul partie du cache.
En admettant qu'il n'y est aucun nouvel article de la journée, inutile de mettre à jour les news. Par contre, si plusieurs utilisateurs arrivent sur le site, le compteur de visite devra lui être à jour. Donc qu'est-ce qu'il ce passe ? Il y à deux possibilités :
Soit les visiteurs sont déjà passés, on leur affichent donc le contenu du cache (donc chargement du retour de requête).
Soit un visiteur dans le total de visiteur est nouveau, on va donc mettre à jour le nombre dans la base de donnée et recharger le cache du compteur de visite uniquement ! (les prochains arrivant sur le site verront le nouveau nombre si ils sont déjà passés, sinon retour à l'étape précédente. Les visiteurs ayant déjà chargés la page (avant mise à jour dans la BDD et du cache) auront l'ancien nombre et ne verront que le nouveau sur rafraichissement de la page).

Ici, si j'avais stocké tout le code html de la page, j'aurai été obligé de recharger toute la page et non une partie uniquement. (il doit bien y avoir la possibilité de faire la même chose même si on stock le code html de la page, mais je reste dans du simple ici).

Un avantage serait une mise à jour partielle du cache. Côté inconvénients, ça oblige à avoir plus de fichiers pour 1 page (quoi que le cache du compteur de visite peut-être réutilisé pour plusieurs pages) et il est possible qu'il y est un ralentissement de la page.

Côté performances entre ce type de cache et un cache html, je n'ai pas comparé les deux donc je ne dis pas que l'un est meilleur que l'autre (et au pire je ne suis pas la pour juger la dessus, même si les performances sont quelque chose de très important).

Voilà j'ai tenté de t'expliquer un peu mieux l'utilité d'un cache comme celui-ci. Il est fort probable que tout soit fesable en stockant du html plutôt qu'un retour de requête. Je tiens encore une fois à préciser que cette façon n'est en aucun cas la meilleur et que j'approuve ta vision concernant les caches, je comprends tout à fait qu'il soit plus logique de mettre du code html dans le fichier directement.

Est-ce que cela te convient ou tu souhaites savoir plus de choses sur d'autres points ?

Merci encore pour tes commentaires :)

Commentaire de neigedhiver le 08/12/2009 00:56:14

Plop,

Merci pour ta réponse.
Je préfère être clair : je ne dénigre pas ta source, je ne fais que lui confronter mes arguments. Je ne prétends pas détenir la vérité, j'énonce simplement ce que je pense, ma manière de voir les choses et je cherche à partager des interrogations. Si tu te poses les questions que je me pose, alors la plus grosse partie des objectifs de mes commentaires est atteinte.

J'entends tes arguments concernant les différents templates et la multiplication des fichiers comme des petits pains. Héhé, bien entendu, j'ai encore des arguments à y confronter ;)

Concernant les templates multiples, je suis persuadé que dans 90% des cas, on peut modifier le template avec uniquement un nouveau CSS. Je ne peux pas apporter de démonstration, mais c'est une conviction que j'ai.

Concernant la multiplication des fichiers de cache : ce n'est en réalité pas un problème. Les fichiers de cache sont gérés par le système de cache, pas par le développeur. Tant que le système de cache sait quel fichier correspond à quoi et qu'il fournit les outils permettant de manipuler facilement et efficacement les fichiers mis en cache, alors s'il y a 30 fichiers différents pour la même page mais avec différents templates, ou s'il faut 50 fichiers à assembler pour composer la page d'accueil, peu importe : le système de cache sait quoi assembler et comment. L'utilisateur n'a pas à mettre le nez dedans, c'est pas son problème. C'est un peu comme si tu cherchais à savoir si ton OS n'utilise pas trop de registres dans la RAM pour fonctionner : c'est pas ton problème, tant qu'il les gère correctement.

Les deux problmatiques sont liées : rien n'empêche de composer une page avec plusieurs fichiers de cache et une partie dynamique, et ce plusieurs fois pour plusieurs templates.
Ainsi, si tu as 15 templates et qu'il faut générer 15 fichiers de cache juste pour les news pour chaque template, je ne vois pas où est le problème : le système de cache doit permettre ça.
Et si tu veux hiérarchiser tes fichiers de cache, pour y voir plus clair quand tu développes ton site, c'est pas un problème non plus : le système de cache est censé être capable de gérer les fichiers quel que soit leur emplacement (chemin/répertoire).
Le cache HTML de la liste de news sera donc généré pour chaque template chaque fois qu'un utilisateur utilisant ce template affiche la page d'accueil, si le fichier de cache n'existe pas déjà.
Ou alors, lorsque tu postes un nouvel article, ton back office va générer les fichiers de cache pour tous les templates, une bonne fois pour toute (puisque de toute façon, la requête ne sera exécutée qu'une seule fois, il n'y a que le template qui est parsé avec des valeurs qui ne changent pas). A ce moment là, pour la génération du cache, peu importe si ça prend 10 secondes : c'est du back office, qui n'est vu que par un seul utilisateur à un instant T. On ne pourrait pas admettre qu'il faille 10 secondes pour poster un message sur un forum, mais un article dans l'admin... les utilisateurs ne sont pas impactés, donc ça peut bien prendre le temps qu'il faut.

Voilà voilà, je vais aller dormir maintenant, parce que quand même...

Commentaire de destinyfr le 08/12/2009 20:38:02

Salut,

Merci pour ton retour :) je suis preneur sur tout :p c'est via d'autres avis que l'on s'améliore de toute façon. Je ne vais pas trop m'étendre sur le sujet pour le moment car les cours me prennent pas mal de temps. Je vais prendre en comptes tes commentaires et améliorer la classe. J'ai déjà commencé mais il m'en reste à faire.

Merci pour tes commentaires, si tu veux rajouter des choses etc.. n'hésite pas ! Je suis au contraire pour :)

Dès que j'ai mis à jour, j'envoie.

Commentaire de destinyfr le 28/12/2009 12:44:17

Mise à jour du code, refonte complète. J'attends vos commentaires :)

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

cache du navigateur [ par booth ] c'est encore moa....Désolé mais j'ai un projet à terminer dans peu de temps alors...J'ai pas trouvé le moyen de forcer le navigateur (et le proxy pend problême de cache [ par sana72 ] bonjour,Pour annuler la mise en cache de mes pages, j'utilise :&lt;? header("Pragma: no-cache"); header("Expires: 0"); header("Last-Modified: " balise, cache :( [ par elanspeech ] Bonjour,J'utilise la balise suivante :&lt;embed src="fichier.wav" width=145 height=25 autostart="false" cache="false" controls="controlpanel"&gt;fichi Vider le cache de l'explorer en programmation Php ou JS [ par Cr0w ] Bonjour,J'aimerai savoir si il existe une fonction en Php ou JavaScript permettant de vider le cache de l'explorer.En effet, j'ai conçu dans le cadre cache limiter [ par brok ] quand j'appelle ma page page.php, je recoit le message d'erreur suivant:Warning: Cannot send session cache limiter - headers already sent (output star Cache JavaScript et images générées... [ par dominion ] Bonjour à tous !Je suis face à un problème qui a l'art de royalement m'énerver : $normal = 'images/button.php?text=text&img=submit.png';$click = 'ima <??> IMAGE DYNAMIQUE PROBLEME DE CACHE IE6 <??> [ par amosc ] amosSalut les gas,Ce probleme n a pas trop de rapport avec PHP dsl ...Je genere une image en php, c est un graphique, tout se passe bien, mais voila l Class POO retourné le nom de l'objet [ par MeTh ] Bonjour,Comment retourné le nom de l'objet déclaré?exemple :$monobjet = new GridR();comment recuperé $monobjet dans ma class?Merci pb de cache ? [ par ronanf235 ] bonjourexplication du contexte : je developpe une appli de sasie de questionnaire, et actuellement, lorsque l'utilisateur clique sur precedent, il re php et google ... ? [ par michelvernet2 ] bonjour,pour éviter un PB de session avec aol, je force la session dans l'adresse, voir : www.nouveauxobjets.com . Pour ceux qui ont la google barre,


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 1,045 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales