Les scripts à jéjé: Partage de la mémoire en php

Discussion dans 'Administration d'un site Web' créé par fandecine, 26 Mai 2005.

  1. fandecine
    fandecine WRInaute passionné
    Inscrit:
    2 Avril 2005
    Messages:
    1 873
    J'aime reçus:
    0
    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 https://www.webrankinfo.com/dossiers/conseils/bon-referencement-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 :wink: Mais je sais que les wrinautes ont beaucoup d'idées!

    ce script permet d'initialiser le block de mémoire partagé:
    Code:
    <?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:
    <?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:
    <?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!
     
  2. shrom
    shrom WRInaute impliqué
    Inscrit:
    5 Juillet 2004
    Messages:
    781
    J'aime reçus:
    0
    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.
     
  3. fandecine
    fandecine WRInaute passionné
    Inscrit:
    2 Avril 2005
    Messages:
    1 873
    J'aime reçus:
    0
    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.
     
  4. shrom
    shrom WRInaute impliqué
    Inscrit:
    5 Juillet 2004
    Messages:
    781
    J'aime reçus:
    0
    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.
     
  5. fandecine
    fandecine WRInaute passionné
    Inscrit:
    2 Avril 2005
    Messages:
    1 873
    J'aime reçus:
    0
    ok shrom! L'exemple choisi n'est pas top! Mais le seul objectif de ce post et d'expliquer le mécanisme de mémoire partagé, c'est tout!
     
  6. itsme
    itsme WRInaute impliqué
    Inscrit:
    13 Octobre 2004
    Messages:
    609
    J'aime reçus:
    0
    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 ;)
     
  7. taybott
    taybott WRInaute discret
    Inscrit:
    12 Janvier 2005
    Messages:
    141
    J'aime reçus:
    0
    Je connaissais pas cet technique (encore bcp de choses a apprendre :roll: ) mais je crois qu'il y a des situations où ça peut être plus pratique d'utiliser ça!!
     
  8. Tex
    Tex WRInaute occasionnel
    Inscrit:
    9 Juillet 2004
    Messages:
    342
    J'aime reçus:
    0
    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 :)
     
  9. Suede
    Suede WRInaute passionné
    Inscrit:
    4 Octobre 2002
    Messages:
    2 441
    J'aime reçus:
    0
    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
     
  10. fandecine
    fandecine WRInaute passionné
    Inscrit:
    2 Avril 2005
    Messages:
    1 873
    J'aime reçus:
    0
    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.
     
  11. ti_ouf
    ti_ouf WRInaute discret
    Inscrit:
    10 Avril 2005
    Messages:
    173
    J'aime reçus:
    0
    Etant donné que tu l'utilises pour palier aux cookies, utilises tu l'ip alors?
     
  12. pedouille
    pedouille WRInaute discret
    Inscrit:
    24 Mai 2005
    Messages:
    80
    J'aime reçus:
    0
    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.
     
  13. ZBoy
    ZBoy Nouveau WRInaute
    Inscrit:
    7 Septembre 2007
    Messages:
    1
    J'aime reçus:
    0
    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
     
Chargement...
Similar Threads - scripts jéjé Partage Forum Date
Sites de scripts PHP, jQuery, Ajax, etc. Le café de WebRankInfo 20 Mars 2022
Scripts de réseau social Le café de WebRankInfo 13 Décembre 2019
Comment cacher des scripts Javascript distants sous Nginx ? Développement d'un site Web ou d'une appli mobile 29 Octobre 2017
Scripts communs à 3 sites Développement d'un site Web ou d'une appli mobile 17 Janvier 2016
Finalement, quelle est la différence entre ces deux scripts ? Développement d'un site Web ou d'une appli mobile 29 Septembre 2015
scripts social network et performances Administration d'un site Web 4 Mai 2015
Quel plateforme utiliser pour partager le développement de scripts ? Développement d'un site Web ou d'une appli mobile 12 Février 2015
Correction du code des scripts bloqués Débuter en référencement 24 Novembre 2014
Scripts payant Développement d'un site Web ou d'une appli mobile 7 Août 2014
liens prèsent dans les scripts Débuter en référencement 8 Juillet 2014
utilisation des scripts sous licences MIT, BSD, et GPL. Débuter en référencement 2 Août 2013
Retour d'expérience et scripts PHP à éviter (OpenX et CaptchaSecurityImages.php) Développement d'un site Web ou d'une appli mobile 18 Avril 2013
internet explorer restricted this page from running scripts or activex controls Développement d'un site Web ou d'une appli mobile 27 Octobre 2012
Positionnement des scripts JS, vitesse et référencement Rédaction web et référencement 16 Janvier 2012
Templates et scripts Demandes d'avis et de conseils sur vos sites 7 Mai 2011
[Page Speed] optimisation des images des scripts des css Développement d'un site Web ou d'une appli mobile 11 Janvier 2011
Ras le cul des scripts kindies ... Demandes d'avis et de conseils sur vos sites 1 Octobre 2010
Blog développement web, design, scripts jQuery & PHP, référencement . Demandes d'avis et de conseils sur vos sites 29 Août 2010
Les scripts PHP qui génèrent des pages HTML (virtuelles) Débuter en référencement 14 Juillet 2010
J'ai 2 scripts et je veux les charger l'un après l'autre Développement d'un site Web ou d'une appli mobile 10 Juillet 2010