XHTML.net

Technology talks by Loïc d’Anterroches

News, articles, PHP, scripts, XHTML/CSS, …

  1. Home
  2. PHP: Hypertext Preprocessor

Compteur Live pour un site

The 2004-08-09 at 20:03 by Loïc d'Anterroches filed under PHP: Hypertext Preprocessor and Scripts.

LiveCount est un script PHP et MySQL permettant d’évaluer le nombre de personnes actuellement en ligne sur votre site en temps réel. Les limitations du système sont présentées avec les détails de l’implémentation.

Principe du compteur live

Un important rappel est que tous les compteurs de ce type sont par définition faux. C’est à dire que vous ne pouvez pas et vous ne saurez jamais exactement le nombre de personnes sur votre site en temps réel. Pourquoi ? Parce que le protocole HTTP ne réalise pas une connexion permanente entre le serveur et l’utilisateur.

Ainsi quand vous regardez une page, puis une autre, le tout dans l’espace de 5 minutes. Les compteurs actuels diront ok, il était là pendant les 5 minutes complètes, alors que vous avez vu la première page et constaté qu’elle était nulle, puis par erreur vous êtes revenu en ouvrant une nouvelle fenêtre de votre navigateur sur le site.

Nous vous proposons donc uniquement un script qui évalue le nombre de visiteurs sur votre site, car nous ne pouvons pas faire mieux.

Explication de la procédure

Nous allons mettre en place un script qui fait 3 choses :

  • Un enregistrement des visiteurs de votre site
  • Un comptage des visiteurs normalement encore en ligne (avec une opération de nettoyage au passage)
  • Un affichage de nombre de visiteurs sur le site

Quand le script s’exécute sur votre serveur il procède donc comme suivant :

  1. Enregistrement du visiteur dans la base de données, on note l’heure et son adresse IP.
  2. Comptage du nombre d’enregistrements dans la base qui ont une adresse IP distincte et qui ne sont pas trop vieux.
  3. Suppression des enregistrement trop vieux.

Le principal problème vient du trop vieux. Pour savoir à combien il faut régler la valeur, je vous conseille de mettre 3 minutes, en effet si votre visiteur regarde sa dernière page il sera toujours considéré comme en ligne 3 minutes plus tard (cela double le temps réel de visite si vos visiteurs restent en moyenne 3 minutes sur votre site).

Le second problème vient de l’utilisation de l’adresse IP. Si plusieurs personnes sont présentes sur le site via un serveur proxy, le système ne compter qu’une unique personne. Un système mélangeant cookies et adresse IP devrait être utilisé pour affiner le résultat, mais le problème du temps moyen de visualisation d’une page ne peut pas être résolu…

Maintenant que vous connaissez les limitations du script que je vous présente on peut commencer à regarder comment il peut être implémenté.

Détails du script et implémentation

Pour utiliser ce script sur votre serveur vous devez avoir PHP et MySQL d’installés.

Code de création de la base MySQL

Vous pouvez créer la table dans n’importe quelle base de données MySQL du moment que vous pouvez y accéder.

#
# Structure de la table 'online'
# 
CREATE TABLE online (  
  timestamp int(15) DEFAULT '0' NOT NULL, 
  ip varchar(40) NOT NULL,    
  fichier varchar(100) NOT NULL,    
  PRIMARY KEY (timestamp), 
  KEY ip (ip),    
  KEY fichier (fichier) 
);
# 

Vous pouvez directement utiliser ce code. Normalement un script comme PHPMyAdmin permet de faire la création directement de cette table. Si vous le mettez dans un fichier online.sql et que vous mettez le tout sur votre serveur (on suppose que vous avez accès à votre serveur en Telnet) tapez cette ligne.

mysql -u votreloginmysql -p votrebasemysql < online.sql

On vous demandera votre mot de passe et on vous dira ok.

le code du script

<?php 
$serveur  = 'nomdevotreserveur'; 
$db_login = 'votrelogin'; 
$db_passe = 'votremotdepasse'; 
$database = 'nomdelabasededonnees'; 

$timeoutsecondes = 300; 
// Le nombre de secondes pendant lesquelles le script considère que
// votre utilisateur est en ligne.  

$timestamp = time();  // on prend l'heure du moment
$timeout   = $timestamp - $timeoutsecondes; 
// à partir de quand les enregistrement ne sont plus valides

mysql_connect($serveur, $db_login, $db_passe); 
$insert = mysql_db_query($database, 
          "INSERT INTO online VALUES (
          '$timestamp','$REMOTE_ADDR','$PHP_SELF')");
// On fait l'insertion dans la base de l'heure actuelle $timestamp
// puis de l'adresse IP du visiteur $REMOTE_ADDR et enfin de
// la page où est le visiteur $PHP_SELF

if(!($insert)) { // l'insertion ne s'est pas faite
    print "Utilisateurs en ligne : Problème d'insertion"; 
} 
$delete = mysql_db_query($database, "DELETE FROM online 
          WHERE timestamp<$timeout"); 
// on supprime tous les enregistrements périmés.
if(!($delete)) { // problème au nettoyage
    print "Utilisateurs en ligne : Problème de nettoyage de la base";
} 
$result = mysql_db_query($database, "SELECT DISTINCT ip 
          FROM online WHERE fichier='$PHP_SELF'"); 
// On recupère les lignes où les utilisateurs sont 
// uniques et sont passés par la page en cours.
if(!($result)) { // Si on n'a un problème à la récupération
    print "Utilisateurs en ligne : Problème de recherche dans la base"; 
} 
$nombre = mysql_num_rows($result); 
// On compte le nombre de résultats trouvés 
mysql_close(); 
// On ferme la connexion à la base de données.

if($nombre <= 1) { 
    print("$nombre utilisateur en ligne"); 
} else { 
    print("$nombre utilisateurs en ligne"); 
} 
?>

Si vous voule que cela soit un compteur global sur toutes les pages où vous faites fonctionner ce script enlevez simplement WHERE fichier=’$PHP_SELF’.

Le script comme vous pouvez le constater est simple. On peut le perfectionner avec par exemple une requète COUNT à la place du SELECT, on peut faire d’autres petites modifications mais globalement cela ne changera pas grand chose…

Un conseil : amusez vous à faire le test avec différentes valeurs de $timeoutsecondes et vous verrez que ce type de compteurs n’est pas forcément très fiable.


Comments from readers

annuaire zen said:

ben trop cool ce petit script, je viens de l'ajouter à ma base de donnée et à mon site, ça marche nickel, merci ! (en passant vraiment bien votre site, une mine d'or).

Ana said:

Salut, le compteur reste bloqué à 1 alors qu'il y a environs 20 personnes en ligne.. ???

Voice your ideas

It is painless and I try not to kill electrons in the process.


Your email is required but will not be shared nor displayed.


Do you think your comment will force me to write even better stuff next time? If so, you simply rock.


Logo of Plume CMS