Tutoriaux > PHP / MySQL > Compteur de visites à l'ip sans MySql
Un petit compteur avec la fonction serialize().
Réaliser un compteur sans bases de données dont le mode de stockage soit aisé n'est pas si difficile que ça. Toute fois si vous possédez une base de données, MySql par exemple, inutile de vous en priver.
Le script, résumé à la fin de ce tutoriel, possède une petite dizaine d'étapes toutes simple que nous allons voir au fur et à mesure. Mais avant ça, regardons plutôt le concept du programme.
[size=16]Les tableaux indexés, petit cours de rattrapage[/size]
Tout le compteur est basé sur une variable de type « array », un tableau qui n'est ni plus ni moins qu'un ensemble de données. Les variables de ce type ce présentes sous une forme particulière, en effet les variables simples de type string (chaîne de caractères) ou int (entier) float (à virgule flottante) double (décimaux) et booléen (vrais faux) associent une valeur unique à la variable ainsi
Citation
<?php
$variable = "ma chaîne de caractères";
echo $variable;
?>
affiche
Code
ma chaîne de caractères
alors que dans un tableau il existe une valeur associée à chaque clés.
Soit les clés sont numérotés dans l'ordre à partir de 0 et on dit alors que le tableau est indexé, soit les clés sont des chaînes de caractères (plus ou moins arbitraires) et on dit alors que le tableau est associatif (soit dit en passant, il peut très bien être les deux), ainsi
Citation
<?php
$tableau_indexe = array('valeur 1', 'valeur 2', 'valeur 3');
print_r($tableau_indexe);
$tableau_associatif = array(
'clée1' => 'valeur 1',
'clée2' => 'valeur 2',
'clée3' => 'valeur 3'
);
print_r($tableau_associatif);
?>
renvoi
Code
Array
(
[0] => valeur 1
[1] => valeur 2
[2] => valeur 3
)
Array
(
[clée1] => valeur 1
[clée2] => valeur 2
[clée3] => valeur 3
)
On accède à une valeur grâce à sa clé :
Citation
<?php
echo $tableau_indexe[0];
echo "<br />\n"; // retour à la ligne
echo $tableau_indexe[2];
echo "<br />\n";
echo $tableau_associatif['clée2'];
?>
renvoi
Code
valeur 1
valeur 3
valeur 2
[size=16]Dans le cas de notre compteur[/size]
le tableau s'appelle « $donnees » et associe à la clé « visites » le nombre de visiteurs et à la clé « requêtes » le nombre de fois que le compteur à été exécuté, autrement dit, le nombres de pages affichés. Les autre clés étant les ip des visiteur et associant la date à laquelle elles ont été enregistrés. Par exemple :
Code
Array
(
[requêtes] => 7
[visites] => 2
[56.47.2.387] => 20050714201032
[217.8.456.87] => 20050714235959
)
[size=16]Comment stocker ce tableau ?[/size]
La fonction « serialize() » permet de transformer un objet en chaîne de caractère et « unserialize() » effectue l'opération inverse.
En effet, quitte à enregistrer les données dans un fichier plutôt que dans une base de donnée, autant le faire sous forme de chaînes de caractères se qui facilite la manipulation.
[size=16]Où stocker ces données ?[/size]
Dans un ficher que le script crée. Par exemple « .htcompteur » qui est un fichier nommé « compteur » auquel on a ajouter « .ht » au début pour interdire son accès depuis Internet et le rendre invisible (en fichier caché) grâce au « . ». Ainsi notre mode de stockage est transparent et sécurisé !
[size=16]Les étapes du script[/size]
Le script commence par un petit bloc tout simple :
Citation
$fichier = '.htcompteur';
if( !file_exists($fichier) ) {
$fp = fopen($fichier, "w");
fwrite($fp, serialize(array()));
fclose($fp);
}
En effet lors de la première exécution, le fichier n'existe pas encore et ces trois lignes permettent de crée le fichier contenant notre tableau... vide.
Cette instruction renseigne sur le nom et le chemin du fichier
Citation
$fichier = '.htcompteur';
il est donc possible de le changer en
Citation
$fichier = '.htCompteurDePagesDeLaMortKiTu';
ou de le placer dans le dossier « tests »
Citation
$fichier = 'tests/.htcompteur';
bref, vous en faites ce que vous voulez !
Citation
$fichier = 'includes/donneesducompteur.txt';
ensuite, la ligne
Citation
$fp = fopen($fichier, "w");
crée le fichier et l'ouvre avec des droit d'écriture, la ligne
Citation
fwrite($fp, serialize(array()));
enregistre dans le fichier un tableau vide sous forme de chaîne de caractères et
Citation
fclose($fp);
referme le fichier.
Notre système en mains, il ne nous reste plus qu'a réaliser le compteur en lui même qui va se dérouler suivant ces étapes :
- une petite série de définition de quelques variables nécessaires
- la récupération des données stockés,
- la suppression des données périmés,
- l'incrémentation (?) des compteurs,
- la définition de variables stockant les données utiles,
- le stockage des données actualisée,
- et l'affichage des valeurs du compteur.
[size=16]Nos variables[/size]
Le nom des clés utilisées pour stocker la valeur des deux compteurs à savoir le nombre de visites et le nombre de pages affichés
Citation
$argument_visites = 'visites';
$argument_requêtes = 'requêtes';
la récupération de l'ip du visiteur
Citation
$ip = $_SERVER['REMOTE_ADDR'];
puis la date et l'heure lors que l'exécution de ce script
Citation
$time = date('YmdGis');
Code
date('YmdGis')
renvoi la date sous la forme d'un timestamp MySql...
[size=16]Et pourquoi pas le timestamp Unix ?[/size]
Le timestamp Unix est le nombres de secondes s'étant écoulées depuis le 1er Janvier 1989.
Il a l'avantage certain de se présenter sous forme d'un entier et est utilisé pas de nombreux programmes pour manipuler les date. Seulement, en raison du nombre de chiffre limités, celui ci n'existera plus en 2039, ayant consommé toute la place, ce qui n'est pas le cas du timestamp Mysql qui n'est pas vraiment un timestamp mais une simple contraction d'une date complète telle que nous la connaissons. Ainsi le 14 Juillet 2005 à 23 heures, noté 2005-07-14 23:00:00 vas se retrouvé sous la forme 20050714230000.
Mon coté perfectionniste sûrement, me tend à utiliser cette deuxième solution, au moins je me dit que mon compteur ne sera pas périmé en 2039 (votre site peut être)
[size=16]Bref[/size]
Le script récupère donc les données contenu dans notre fichier
Citation
$lignes = file($fichier);
$donnees = unserialize($lignes[0]);
« $lignes » est un tableau indexé contenant une ligne du fichier par clés, « unserialize($lignes[0]) » rend la forme d'un tableau à nos donnés contenu dans la ligne 1. Nous voici donc avec notre tableau « $donnees » prêt à l'emploi !
Citation
foreach( $donnees as $cle => $valeur )
{
if( substr($valeur, 0, 8) != substr($time, 0, 8) &&
$cle != $argument_visites &&
$cle != $argument_requêtes ) {
unset($donnees[$cle]);
}
}
Une boucle passe en revue toutes les clés du tableau tout en vérifiant que la clé est bien une ip, la supprime si la date « date » d'hier.
Décomposons.
Code
&& $cle != $argument_visites && $cle != $argument_requêtes
Exclu les deux clés stockant les valeurs du compteurs.
Code
substr($variable, 0,
Ne prend en compte que les 8 premiers caractère de la chaîne, ainsi seul la différence de date est testé et non l'heure.
[size=16]Oui mais alors, pourquoi stocker l'heure ?![/size]
Arf ben, c'est le « ça peut toujours servir » qui gagne ! Et oui, imaginons que vous vous sentez de faire un autre petit script qui, sur le modèle du début de celui ci récupère les donnée et les affiche, et ben paf!, vous avez de quoi surveillé les heures de passages (enfin d'arrivée) des visiteurs. Et en en remettant une couche, il est possible de stocker rapidement l'url par laquelle ce compteur à été exécuté (où le visiteur se trouve sur le site) ainsi que l'heure et l'ip correspondante, bref un vrai script d'espionnage des visiteurs, ou plutôt un script de statistiques.
[size=16]Les compteurs sont ensuite incrémenté[/size]
« incrémenté » !?? moi parlé ~&*/ et toi rien comprendre ? Ok, ça veut surtout dire que l'on ajoute 1 à un nombre. Je vous épargne de la pré-incrémentation, post-incrémentation, pré-décrémentation, post-décrémentation (pour l'instant) mais bon, c'est tout juste une histoire de +1, -1.
Citation
$donnees[$argument_requêtes]++;
if( !$donnees[$ip] ) {
$donnees[$argument_visites]++;
$donnees[$ip] = $time;
}
À noté qu'on incrémente la valeur requête à chaque fois alors que celle des visiteur l'est si et seulement si (ma prof de math déteint sur moi !) le visiteur n'a pas encore été enregistrée.
Code
if( !$donnees[$ip] )
Et donc si ce n'est pas le cas, on ajoute la date associée à l'ip et on incrémente les visites
Code
$donnees[$argument_visites]++;
$donnees[$ip] = $time;
[size=16]Ensuite...[/size]
Alors ça
Citation
$nb_visiteurs = $donnees[$argument_visites];
$nb_aujourdhui = count($donnees)-2;
$nb_requêtes = $donnees[$argument_requêtes];
c'est juste pour faire joli ici
Citation
echo $nb_visiteurs." visiteurs dont ";
echo $nb_aujourdhui." aujourd'hui, ";
echo $nb_requêtes." pages affichés ";
c'est beau hein ? Plus sérieusement, le nombre de visiteurs journaliers sont obtenu simplement en comptant le nombre d'ip enregistrés, c'est à dire ne nombre d'enregistrements que contient le tableau « $donnees » moins 2, à savoir « $donnees['visites'] » et « $donnees['requêtes'] ».
[size=16]On enregistre nos données[/size]
Citation
$fp = fopen($fichier,"w");
fwrite($fp, serialize($donnees));
fclose($fp);
Ça ressemble quand même à du déjà vu...
[size=16]On affiche fièrement le compteur[/size]
Citation
echo $nb_visiteurs." visiteurs dont ";
echo $nb_aujourdhui." aujourd'hui, ";
echo $nb_requêtes." pages affichées ";
Quoi que, ces instruction peuvent êtres déplacées à l'endroit idéal pour afficher les résultats (après le script bien sur)
Si ce script se retrouve dans un page appelée « compteur.php », il est tout à fait possible de l'include dans une autre page en php comme ceci :
Citation
include_once('compteur.php');
ou directement dans une page html grâce à du javascript :
Code
<script language="javascript" src="compteur.php"></script>
Voili voilou, il ne manque plus qu'une chose
[size=16]Le script en entier[/size]
Citation
<?php
/*
* Si le fichier où l'on stock,
* les données n'existe pas encore
* on le crée.
*/
$fichier = '.htcompteur';
if( !file_exists($fichier) ) {
$fp = fopen($fichier, "w");
fwrite($fp, serialize(array()));
fclose($fp);
}
/*
* Définition de variables
* nécessaire au compteur :
* - deux termes constants,
* - l'ip du visiteur,
* - la date et l'heure.
*/
$argument_visites = 'visites';
$argument_requêtes = 'requêtes';
$ip = $_SERVER['REMOTE_ADDR'];
$time = date('YmdGis');
/*
* Récupération des données du
* compteur précédemment stockées.
*/
$lignes = file($fichier);
$donnees = unserialize($lignes[0]);
/*
* Pour chaque clés du tableau de données
* qui ne soit pas attribuée aux visite et aux requêtes
* si la valeur correspond à une date antérieur
* au même jour, on supprime l'ip du visiteur.
*/
foreach( $donnees as $cle => $valeur )
{
if( substr($valeur, 0, 8) != substr($time, 0, 8) &&
$cle != $argument_visites &&
$cle != $argument_requêtes ) {
unset($donnees[$cle]);
}
}
/*
* On incrémente ( ajoute +1 ) la valeur
* du nombre de requêtes.
* Si l'ip n'est pas encore enregistrée,
* on incrémente la valeur du nombre de visites
* et on ajoute l'ip dans le tableau accompagné
* de la date et de l'heure de l'exécution.
*/
$donnees[$argument_requêtes]++;
if( !$donnees[$ip] ) {
$donnees[$argument_visites]++;
$donnees[$ip] = $time;
}
/*
* On effectue un petit report de variable
* pour une utilisation ultérieur plus aisée.
*/
$nb_visiteurs = $donnees[$argument_visites];
$nb_aujourdhui = count($donnees)-2;
$nb_requêtes = $donnees[$argument_requêtes];
/*
* On stock le tableau dans le fichier de données
* en écrasant sa valeur précédente.
*/
$fp = fopen($fichier,"w");
fwrite($fp, serialize($donnees));
fclose($fp);
/*
* On affiche les résultats du compteur.
*/
echo $nb_visiteurs." visiteurs dont ";
echo $nb_aujourdhui." aujourd'hui, ";
echo $nb_requêtes." pages affichées ";
?>
Enjoy !
Arcus
Par Arcus
, Le 05 Mai 2005 à 20h08
Ce tutoriel est la propriété d'Aidoweb et ne peut en aucun cas être copié.
Bonjour à tous ! Vraiment ce compteur par contre si j'insère ce compteur sur 10 pages exemples pour avoir 10 compteurs et que je souhaiterais faire un top 10 des compteur en prenant en compte le résultat de chaque compteur. Es-ce possible? Pouvez-vous m'aider?
Merci du script il fonctionne très bien, avant j'en utilisais un autre mais il ne me disais pas combien de visiteur par jour donc je ne savais pas si c'était moi ou les visiteurs qui faisait évoluer mon compteur
merci , franchement tres bien expliqué
Merci infiniment.
Déterrage de tuto... mais bon je le trouve très instructif, détaillé PARFAIT pour revoir l'utilisation de tableau, variable et fonction... Bon code Maison pour se creuser les méninges sur son propre compteur (et éviter de télécharger les trucs tout fait...)
super merci =)
En effet ça bug mais je ne chercherai pas à le résoudre.
Je ne te conseil plus de l'utiliser d'autant plus que le concept de "compteur à ip" est completement dépassé... de même pour le stockage des données dans un petit fichier comme ça.
Dans un but didactic tu pourrais faire tes statistiques toi même mais le mieux, c'est de pas se prendre la tête :
http://piwik.org/
http://www.google.com/analytics/
http://www.phpmyvisites.net/
Bonjour,
Voila un détérage de post mais j'ai utilisé ce code et j'ai le même problème de rafarel. Mon compteur s'est réinitialisé à 41 visites.
Y-a-t il une solution afin que le compteur ne se reset plus ?
J'ai regardé sur le forum mais je n'ai pas trouvé.
Merci
Merci Alainb et rafarel pour vos apports
Je ne ne vérifi malheureusement pas assez les commentaires des tutos (pensez à poser vos questions sur le forum )
- pour Alainb merci c'est très juste pour l'histoire du visiteur qui se pointe juste avant minuit, mais rien à été ajouté pour souci de simplicité (hélas oui je t'entend lol)
Dans le même genre il y a les visiteurs derriere un routeur, à la maison de plus en plus ou en entreprise qui ne sont pas différenciés car possédant la même adresse ip... mais bon, les défauts comme les avantages sont dans le titre ! Pour moi c'est parfait pour une mini page web faite à "l'arache" mais surement pas pour un site en entier que l'on édite régulièrement.
Après le mieux c'est sur c'est toujours d'utiliser une table mysql ou deux pour contabiliser les statistiques de visites, durées, navigateurs différents utilisés... différencier les visiteurs tant sur leur ip qu'a l'aide de sessions etc...
-pour répondre à rafarel:
je n'est pas observé de bug mais cela ne m'étonne gère dans le sens ou je n'ai pas vraiment pris le temps dans la mesure ou je n'utilise pas ce compteur...
Si ton pb est encore d'actualité, poste un sujet dans aide au site web, je ne serai pas le seul à t'aider
Salut Arcus.
J'ai fait mon compteur de visite en m'inspirant de ton code.
Le problème c'est que le compteur se reinitialise de temps en temps et c'est tres enuyeux! (au alentour des 2000 a 3000 visites)!
Sais tu d'ou cela pourrais venir?
Merci
Très bien, ça m'a fait comprendre un peu mieux l'écriture et la lecture dans un fichier.
Cela dit, il existe une petite erreur logique : tu effaces l'ip des visiteurs de la veille avant de vérifier si l'ip du visiteur connecté existe, pour incrémenter le nombre total de visiteurs. Ce qui fait qu'un visiteur connecté à 23h55 (par exemple) et qui reste connecté jusqu'après 00h00 va compter pour deux dans le nombre total de visites (j'ai fait l'essai). Pour corriger ce petit bug j'ai donc rajouté à la suite de ton script le code suivant:
<?php
$fichier_total = '.htcompteur_total';
if( !file_exists($fichier_total) ) {
$fp = fopen($fichier_total, "w");
fwrite($fp, serialize(array()));
fclose($fp);
}
$duree_sess_max = 43200;//durée de stockage de l'ip avant effacement (exprimé en seconde et modifiable, ici 12h).
$argument_visites_total='visites_total';
$ip = $_SERVER['REMOTE_ADDR'];
$date = strtotime("now");
$lignes_total = file($fichier_total);
$donnees_total = unserialize($lignes_total[0]);
foreach( $donnees_total as $cle => $valeur )
{
if ($cle != $argument_visites_total && ($date - $valeur > $duree_sess_max ))
{
unset($donnees_total[$cle]);
}
}
if( !isset($donnees_total[$ip]) ) {
$donnees_total[$argument_visites_total]++;
$donnees_total[$ip] = $date;
}
$nb_visiteurs = $donnees_total[$argument_visites_total];
$fp = fopen($fichier_total,"w");
fwrite($fp, serialize($donnees_total));
fclose($fp);
?>
Je rappelle qu'il s'agit d'un complément à mettre à la suite du code original (avant l'affichage des résultats) sinon vous n'obtiendrez qu'un compteur de visites totales (des bouts de code sont redondants avec l'original pour permettre une utilisation autonome de ce script comme simple compteur de visites totales).
Petite contrariété, il y aura peut-être des pb de fonctionnement en 2039...Je ne précise pas pourquoi, pas plus que je ne rentre dans l'explication du code puisque c'est la mise en application du tuto très bien documenté d'Arcus (encore une fois, merci Arcus) avec un timestamp Unix.
Si vous avez la soluce pour faire aussi simple et éternel...merci de nous le faire savoir.
Ah oui, une dernière précision: pour que ces scripts fonctionnent chez un hébergeur professionnel vous aurez peut-être besoin (ça dépend des serveurs) de donner l'autorisation de lecture et d'écriture sur les fichiers ".htcompteur" ou/et ".htcompteur_total" au niveau du serveur. Par exemple dans FileZilla (logiciel ftp gratuit, voir google) clic droit sur le fichier distant en question puis "attributs de fichiers" puis indiquer 777 ou cocher toutes les cases (pas sûr du tout que dreamweaver ait cette fonctionnalité dans son module de transfert ftp).
excellent tuto, merci
Ouah, je vais changer le mien qui tourne sur mySQL pour celui-ci, c'est plus rapide que des requêtes!
Merci Arcus, ça nous évite de s'embêter...
bien joué arcus....
lol ... dans les commentaires ! ( style g le temps d'ajouter une notation aux tutoriaux... pouzy devra attendre encore un peu )
pour les suggestions, les points flou ( les demandes de tutos, pourquoi pas) c'est dans le forum Tutoriaux que ça se passe !
franchement .... super joli et compréhensible
10/10 =D ( ou qu'il est le scipt pour noter les tutos ? )
Wahou, ça c'est de l'énorme tuto comme on les aime ! :love:
Tutoriaux > PHP / MySQL > Compteur de visites à l'ip sans MySql