Les scripts à jéjé: Partage de la mémoire en php
13 messages • Page 1 sur 1
Consultez la formation à Google Analytics de WebRankInfo / Ranking Metrics
Les scripts à jéjé: Partage de la mémoire en php
Me voici de retour avec un autre script. Cette fois-ci, il s'agit de trouver une alternative aux cookies et aux variables de session pour stocker des informations relatives à un visiteur de votre site.
Les cookies s'acquitent généralement bien de cette tache, encore faut-il que votre visiteur les accepte (20% de mes visiteurs n'acceptent pas les cookies!)
Les variables de session sont également un bon moyen de conserver des variables d'une page à l'autre mais présentent deux inconvegnants:
- le nombre de sessions n'est pas ilimité
- le passage de variables de session dans l'url peut avoir de graves incidence sur la prise en compte de vos pages par les moteurs de recherche http://www.webrankinfo.com/analyses/php/sessions.php
php nous fournis une alternative avec la possibilité de créer des blocks mémoire partagées accessible à tout les script fonctionnant sur le serveur(gestion des droit d'accés identique à la gestion des droits d'accés fichier linux) grace à un identifiant.
L'exemple dont je donne les sources permet de stocker dans un file de 50 enregistrement, l'ip d'un visiteur et d'y assoicier une valeur de 0 à 9. Le timestamp correspondant à la date/heure de création ou de mise ajour de la valeur est également stocké ce qui permet de faire tourner la file de façon à ce que lorsque les 50 enregistrements sont utilisés, on écrase le plus ancien. (une manère pour obtenir dans un espace fini une capacité pseudo infinie de stockage si on la rapproche à la durée de vie de l'information)
Attention: c'est un exemple pour expliquer le mécanisme! à vous d'immaginer comment utiliser cette fonctionnalité.
Par exemple, sur le site de mon profil, je gere 4 onglets en DHTML sur la page d'accueil. Ce mécanisme me permet de mémoriser sur quel onglet de la page d'accueil était le visiteur afin de restituer le contenu de cet l'onglet lorsque l'internaute:
- revient sur page d'accueil
- utilise les bouton prec et suiv de son navigateur
Les autres utilisations étant disons... plus stratégiques, je n'en parlerais pas ici
Mais je sais que les wrinautes ont beaucoup d'idées!
ce script permet d'initialiser le block de mémoire partagé:
celui-ci permet de détruire le block de mémoire partagée et libère la mémoire!
enfin, le script suivant permet de lire ( appel sans parametre dans l'url) ou d'écrire une valeur dans le bloc de mémoire partagée (appel avec le parametre Val=votrevaleur dans l'url methode GET):
Voila! J'utilise la mémoire partagée pour de nombreuses taches sur mes sites et cela fonctionne trés bien en consommant peu de ressources!
Les cookies s'acquitent généralement bien de cette tache, encore faut-il que votre visiteur les accepte (20% de mes visiteurs n'acceptent pas les cookies!)
Les variables de session sont également un bon moyen de conserver des variables d'une page à l'autre mais présentent deux inconvegnants:
- le nombre de sessions n'est pas ilimité
- le passage de variables de session dans l'url peut avoir de graves incidence sur la prise en compte de vos pages par les moteurs de recherche http://www.webrankinfo.com/analyses/php/sessions.php
php nous fournis une alternative avec la possibilité de créer des blocks mémoire partagées accessible à tout les script fonctionnant sur le serveur(gestion des droit d'accés identique à la gestion des droits d'accés fichier linux) grace à un identifiant.
L'exemple dont je donne les sources permet de stocker dans un file de 50 enregistrement, l'ip d'un visiteur et d'y assoicier une valeur de 0 à 9. Le timestamp correspondant à la date/heure de création ou de mise ajour de la valeur est également stocké ce qui permet de faire tourner la file de façon à ce que lorsque les 50 enregistrements sont utilisés, on écrase le plus ancien. (une manère pour obtenir dans un espace fini une capacité pseudo infinie de stockage si on la rapproche à la durée de vie de l'information)
Attention: c'est un exemple pour expliquer le mécanisme! à vous d'immaginer comment utiliser cette fonctionnalité.
Par exemple, sur le site de mon profil, je gere 4 onglets en DHTML sur la page d'accueil. Ce mécanisme me permet de mémoriser sur quel onglet de la page d'accueil était le visiteur afin de restituer le contenu de cet l'onglet lorsque l'internaute:
- revient sur page d'accueil
- utilise les bouton prec et suiv de son navigateur
Les autres utilisations étant disons... plus stratégiques, je n'en parlerais pas ici
ce script permet d'initialiser le block de mémoire partagé:
- Code: Tout sélectionner
<?php
$enre=time()."-xxxx.xxxx.xxxx.xxxx-x"; //on génére la chaine de caractères par défaut
$mem=""; // on initialise la variable mémoire
for($i=0;$i<50;$i++) { // on initilise la variable mémoire avec 50 enregistrements
$mem.=$enre;
if($i!=49) $mem.=";"; // on sépare chaque enregistrement par le car ";" sauf en fin de mémoire
}
$shm_id = @shmop_open(0xf00, "c", 0644, strlen($mem)); // création du block mémoire partagé
if(!$shm_id) { // on vérifie si la créatioon du block mémoire partagé a réussi
echo "<div align=center>Erreur: Impossible de créer la mémoire partagée.</div><br>";
} else {
$shm_bytes_written = @shmop_write($shm_id, $mem, 0); // Ecriture dans le block de mémoire partagée
echo "<div align=center>Création de la mémoire partagée.</div><br>";
}
?>
celui-ci permet de détruire le block de mémoire partagée et libère la mémoire!
- Code: Tout sélectionner
<?php
$shm_id = @shmop_open(0xf00, "w", 0, 0); // création d'un handle pour notre block mémoire
shmop_delete($shm_id); // destruction du block mémoire partagée
echo 'block mémoire detruit';
?>
enfin, le script suivant permet de lire ( appel sans parametre dans l'url) ou d'écrire une valeur dans le bloc de mémoire partagée (appel avec le parametre Val=votrevaleur dans l'url methode GET):
- Code: Tout sélectionner
<?php
if(isset($_GET['Val'])) $Val=$_GET['Val']; //on récupére la valeur à écrire dans le block mémoire si elle existe
$shm_id = @shmop_open(0xf00, "w", 0, 0); // on crée un handle pour acceder à notre block mémoire partagé
if ($shm_id) { // le block mémoire partagé existe
$ok=sem_get (0xf00); // demande de lecture du block mémoire partagée puis interdit l'acces au block mémoire partagé
if(sem_acquire ($ok)) { // l'accés au block mémoire est authorisé
$shm_size=@shmop_size ($shm_id); // lecture de la taille du block mémoire partagée
$tmp=substr(@shmop_read($shm_id, 0, $shm_size),0,16499); // lecture du block mémoire partagée
$tab=split(";",$tmp); // création d'un tableau d'enregistrement à partir du block mémoire partégée
$trouve=false;
$mem=array();
for($i=0;$i<50;$i++) { // on récupére nos valeur du bloc mémoire partagé dans un tableau
$val=split('-',$tab[$i]);
$Enre=array ('time' => $val[0], 'ip' => $val[1], 'value' => $val[2]);
$mem[$i]=$Enre;
if(str_replace('*','',$Enre['ip'])==trim($_SERVER['REMOTE_ADDR'])) { // on recherche si l'ip de l'internaute existe déjà
$trouve=true; // l'ip existe
$mem[$i]['time']=time(); // on met la date à jour
if(isset($_GET['Val'])) $mem[$i]['value']=$Val; // si valeur passée en paramétre, on la stocke
$memvalue=$mem[$i]['value']; // on lit la valeur correspondant à l'ip de l'internaute
}
}
sort($mem); // on trie notre tableau par date d'ancienneté
if(!$trouve) { // l'ip de l'internaute n'existe pas
$mem[0]['time']=time(); // on stocke la date actuelle
$mem[0]['ip']=trim($_SERVER['REMOTE_ADDR']); // on stocke l'ip de l'internaute
if(isset($_GET['Val'])) $mem[0]['value']=$Val; else $mem[0]['value']=1; // ons stocke la valeur passée en paramètre ou 1 par défaut
$memvalue=$mem[0]['value']; // on récupére la valeur associée à l'ip
}
$memwrite=""; // initialise une chaine vide
for($i=0;$i<50;$i++) { // on reconstitue une chaine avec nos 50 enregistrements
$memwrite.=$mem[$i]['time'].'-'.str_pad($mem[$i]['ip'],15,'*',STR_PAD_RIGHT).'-'.substr($mem[$i]['value'],0,1); // l'ip est complétée par "*" pour atteindre 15 caractères
if($i!=$memsize-1) $memwrite.=';';
}
$shm_bytes_written = @shmop_write($shm_id, $memwrite, 0); // sauvegarde le block memoire partagé
sem_release($ok);// autorise la lecture du block mémoire partagée
}
}
echo $memvalue; // on affiche la valeur 'associée à l'ip de l'internaute
exit(); // fin du script?>
Voila! J'utilise la mémoire partagée pour de nombreuses taches sur mes sites et cela fonctionne trés bien en consommant peu de ressources!
Juste 2 remarques:
1) l'identifiant est dans ce cas l'adresse IP du visiteur: dangereux si on a des visiteurs venant de AOL, Tiscali ... qui on la même IP à cause des proxy
2) la mémoire partagée n'est pas une alternative aux sessions, mais un autre moyen de stocker des informations.
1) l'identifiant est dans ce cas l'adresse IP du visiteur: dangereux si on a des visiteurs venant de AOL, Tiscali ... qui on la même IP à cause des proxy
2) la mémoire partagée n'est pas une alternative aux sessions, mais un autre moyen de stocker des informations.
shrom a écrit:Juste 2 remarques:
1) l'identifiant est dans ce cas l'adresse IP du visiteur: dangereux si on a des visiteurs venant de AOL, Tiscali ... qui on la même IP à cause des proxy
2) la mémoire partagée n'est pas une alternative aux sessions, mais un autre moyen de stocker des informations.
Comme je le précise dans le post, ce n'est qu'un exemple! De plus le danger dépends des donnnées stockées (lorsque c'est juste le contexte d'une page, c'est pas grave)
Enfin, je précise bien qu'il existe d'autres moyens, dont les session, en renvoyant à un article sur les problèmes engendrés par les variables de session passées dans l'url.
fandecine a écrit:Comme je le précise dans le post, ce n'est qu'un exemple! De plus le danger dépends des donnnées stockées (lorsque c'est juste le contexte d'une page, c'est pas grave)
Ben si ton application mélange les données entre tous les utilisateurs AOL parce qu'ils ont la même IP, c'est quand même génant
D'ailleurs, le stockage en mémoire partagée peut très bien être utilisé avec les sessions.
Me voici de retour avec un autre script. Cette fois-ci, il s'agit de trouver une alternative aux cookies et aux variables de session pour stocker des informations relatives à un visiteur de votre site.
C'est effectivement une technique peu connue (et peu utilisee) mais ce n'est qu'une technique de stockage parmis d'autres (base, fichier)...
... et en aucun cas une alternative.
Il ne faut pas confondre moyens et objectifs
le principal interet de la memoire partagée c'est de stocker des resultats de requetes ou des generations lourdes pour fournir un systeme de cache sans accés disque/bdd et donc instantané.
bravo a fandecine pour son exemple démonstratif, meme si pour stocker de simples variables les sessions restent quand meme la meilleure solution (bien evidemment il est preferable de les désactiver au passage des bots pour le referencement), mais le but ici etait de faire du proof of concept
bravo a fandecine pour son exemple démonstratif, meme si pour stocker de simples variables les sessions restent quand meme la meilleure solution (bien evidemment il est preferable de les désactiver au passage des bots pour le referencement), mais le but ici etait de faire du proof of concept
Juste une question :
Dans ton cas, tu utilises l'IP pour identifier à quel visiteurs appartient la pile. Comme dit précédemment, l'IP n'est pas forcément une bonne méthode donc il faudra un autre identifiant pour identifier ton visiteur. Par exemple, un identifiant de session...
amha ta méthode est plutot complementaire des sessions pour stocker des données que tu ne peux peut-etre pas stocker avec les identifiants de sessions (?).
François
Dans ton cas, tu utilises l'IP pour identifier à quel visiteurs appartient la pile. Comme dit précédemment, l'IP n'est pas forcément une bonne méthode donc il faudra un autre identifiant pour identifier ton visiteur. Par exemple, un identifiant de session...
amha ta méthode est plutot complementaire des sessions pour stocker des données que tu ne peux peut-etre pas stocker avec les identifiants de sessions (?).
François
En fait, je crois que j'ai vraiment mal choisi l'exemple, mais je pouvais pas faire trop long!
Tous les exemples que vous donnez sont valables bien entendu.
Mais, maintenent, imaginez que vous souhaitez afficher sur une page d'un annuaire, le nombre de visite d'un site. La solution classique (requette Mysql sur la BDD) présente deux inconvegnants:
- consommation de ressources
- rends innopérant et innutile la mise en cache de la pages (voir mon premier script)
Par conte, vous pouvez creer un tableau en memoire partage avec l'id du lien et le nombre de fois qu'il a été cliqué. C'est rapide et econnome en ressources et vous permet de mettre la page en cache. Ensuite, il suffit de faire un cron qui une fois/jour consolide votre BDD avec les resultats de la mémoire partagés et reinitialise la mémoire partagée.
Tous les exemples que vous donnez sont valables bien entendu.
Mais, maintenent, imaginez que vous souhaitez afficher sur une page d'un annuaire, le nombre de visite d'un site. La solution classique (requette Mysql sur la BDD) présente deux inconvegnants:
- consommation de ressources
- rends innopérant et innutile la mise en cache de la pages (voir mon premier script)
Par conte, vous pouvez creer un tableau en memoire partage avec l'id du lien et le nombre de fois qu'il a été cliqué. C'est rapide et econnome en ressources et vous permet de mettre la page en cache. Ensuite, il suffit de faire un cron qui une fois/jour consolide votre BDD avec les resultats de la mémoire partagés et reinitialise la mémoire partagée.
Je trouve que c'est un bon moyen de se passer des sessions et des cookies. Il a déjà bien maché le travail, il reste à trouver un moyen d'identifier un utilisateur de façon unique. On pourrait imaginer un algorithme qui ne se base pas uniquement sur l'adresse ip, mais sur d'autres paramètres pour identifier de façon stable.
Sinon, il faudrait également mettre toute la soupe dans une belle classe, avec des fonctions simples de lecture / écriture, et là, je crois que tu tiens une bonne alternative.
Sinon, il faudrait également mettre toute la soupe dans une belle classe, avec des fonctions simples de lecture / écriture, et là, je crois que tu tiens une bonne alternative.
Salut à tous,
Je viens de découvrir ce post car je cherchais le meilleur moyen de mettre à disposition des données partagées à tous mes visiteurs. En fait, je suis en train de créer un jeu en PHP, et je trouvais ça lourd que chaque utilisateur lance l'instanciation redondante de tous les objets utiles ( l' écran de jeu, les ennemis, les autres joueurs, les objets au sols, etc...) alors que ce sont les MEMES pour tous les joueurs qui se trouvent au meme endroit.
J'avais pensé d'abord à la méthodes qui consiste à fixer un identifiant de session choisi (qui devient par là une session commune) et d'y enregistrer mes objets/variables: inconvénient je pense la mémoire vive utilisée puis apparemment aussi un mécanisme de blocage de session par PHP au bout d'un moment. Bref
Pour l'instant j'étais parti sur du cache en XML de mes objets, l'affichage de données reviendrai à afficher ces XML, la modification de données à mettre à jour la base de données puis dans la foulée le/les fichiers de cache concernés.
Ca me paraissait pas trop mal niveau performance PHP et MySQL, mais cette discussion m'a vraiment interpelé je ne connaissait vraiment pas ce système : les données sont donc bien sur le disque et pas en mémoire vive? Dans ce cas là, la lecture/ecriture dans ce/ces fichiers n'est-t-elle pas nettement plus lente que l'accès à la base? Et enfin (!), y'a-t-il une restriction dans Apache pour cette option où serait-ele active sur n'importe quel hébergement PHP?
C'était long! Merci d'avance!
ZBoy
Je viens de découvrir ce post car je cherchais le meilleur moyen de mettre à disposition des données partagées à tous mes visiteurs. En fait, je suis en train de créer un jeu en PHP, et je trouvais ça lourd que chaque utilisateur lance l'instanciation redondante de tous les objets utiles ( l' écran de jeu, les ennemis, les autres joueurs, les objets au sols, etc...) alors que ce sont les MEMES pour tous les joueurs qui se trouvent au meme endroit.
J'avais pensé d'abord à la méthodes qui consiste à fixer un identifiant de session choisi (qui devient par là une session commune) et d'y enregistrer mes objets/variables: inconvénient je pense la mémoire vive utilisée puis apparemment aussi un mécanisme de blocage de session par PHP au bout d'un moment. Bref
Pour l'instant j'étais parti sur du cache en XML de mes objets, l'affichage de données reviendrai à afficher ces XML, la modification de données à mettre à jour la base de données puis dans la foulée le/les fichiers de cache concernés.
Ca me paraissait pas trop mal niveau performance PHP et MySQL, mais cette discussion m'a vraiment interpelé je ne connaissait vraiment pas ce système : les données sont donc bien sur le disque et pas en mémoire vive? Dans ce cas là, la lecture/ecriture dans ce/ces fichiers n'est-t-elle pas nettement plus lente que l'accès à la base? Et enfin (!), y'a-t-il une restriction dans Apache pour cette option où serait-ele active sur n'importe quel hébergement PHP?
C'était long! Merci d'avance!
ZBoy
13 messages • Page 1 sur 1
Formation recommandée sur ce thème :
Formation Google Analytics : en 2 jours, apprenez comment exploiter l'essentiel des possibilités de l'outil de mesure d'audience de Google. Formation animée par Julien Coquet, expert certifié officiellement par Google Analytics.
Tous les détails sur le site Ranking Metrics : programme, prix, dates et lieux, inscription en ligne.
Lectures recommandées sur ce thème :
- WebRankInfo lance la publicité collaborative
- Le partage des tags dans Google Reader
- Orange Favoris, pour mémoriser et partager en ligne ses sites préférés
- Le cadeau de Noël 2007 de Google AdSense
- NTIC et éthiques : la valeur de l'information en ligne (rapport de DESS)
- La plateforme de blogs TextCube rachetée par Google
- Google acquiert YouTube pour 1,65 Md$
- Yahoo! Questions/Réponses veut développer les réseaux de connaissances
Qui est en ligne
Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 0 invités









le forum