Sommaire:
Problematique:
Voila des questions récurrentes que se pose de nombreux webmaster. Le dénominateur commun de toutes ces questions est la localisation d’un visiteur, c’est a dire déterminer de quel pays vient chaque visiteur.
La clef de voute de cette localisation est l’Adresse IP de votre visiteur. Il existe aujourd’hui des outils, des API et des librairies permettant de déterminer le pays de provenance en fonction de l’adresse IP.
Nous considérerons ici des exemples pour LAMP (Linux, Apache, MySQL Php), même si il vous sera évidement possible de transposer tout cela a votre propre environnement.
Intéressons nous tout d’abord a l’adresse IP de votre visiteur. Il est assez facile de l’obtenir en utilisant en PHP l’entrée REMOTE_ADDR de votre variable serveur $_SERVER.
Ainsi vous pouvez récupérer l’adresse IP de votre visiteur le code suivant:
// Recuperation de l'addresse IP $ip = $_SERVER['REMOTE_ADDR'] ; // Affichage de l'Addrese IP echo'Votre IP est: <b> $ip </b>';
Le principe est simple, il existe des tables associant chaque Adresses IP ou plages d’adresses IP a une localisation (Pays, Latitude, Longitude …) Maxmind est une société connu pour sa base de donnée de localisation.
Elle propose deux solutions:
Nous allons nous intéresser a Geolite puisque cette solution est gratuite. Maxmind fournit un fichier CSV contant les plages d’adresse IP et le Pays associe.
Comme vous pouvez le voir chaque ligne est constituée de 6 ‘champs’:
Vous pouvez bien sur insérer toutes ses données dans une base de donnée SQL ou autre mais ce n’est pas l’objet de notre article. Remarque la notion de ‘Numéro IP’. Le ‘Numéro IP’ permet de transformer l’adresse IP en un numéro unique et permettra ainsi de déterminer facilement des plages d’adresses IP. On peut pourra donc utiliser les operateurs < ou >.
En posant que l’addresse IP est de la forme w.x.y.z voici l’opération qui permet de transformer une Adresse IP en Numéro IP:
Alors Numero IP = 6777216*w + 65536*x + 256*y + z
On commence par diviser l’adresse IP en 4 entité w. x, y et z grâce a la fonction preg_split, puis on applique la formule ci dessus.
Voici une fonction PHP pour faire cela:
function generer_num_ip($addr_ip)
{
$decomposition = preg_split( '/[.]+/', $addr_ip);
$numip = (double) (16777216*$decomposition[0] + 65536*$decomposition[1] + 256*$decomposition[2] + $decomposition[3]);
return( $numip );
}
Tout d’abord rendez vous sur le site de Maxmind pour télécharger le CVS contenant toute la base de géolocalisation:
http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip
Maintenant que l’on a le numéro IP associée a l’adresse IP que l’on désire localiser il faut trouver a quel Pays ce Numéro IP appartient. Pour cela il faudra un bout de soft pour:
Voici une fonction PHP qui fera cela parfaitement:
function process_csv($file, $ipnum)
{
// Ouvrir le fichier
$handle = fopen($file, 'r');
while (($data = fgetcsv($handle, 1000, ',')) !== FALSE)
{ // Pour Chaque Ligne Lu
// On regarde si le Numero IP se trouve dans
// la plage de la ligne lu
if( ($ipnum >= $data[2]) &&
($ipnum <= $data[3]) )
{
// Sortir du while
break;
}
}
// Fermeture du fichier
fclose($handle);
return $data[5];
}
Notez qu’il est recommande dans un environnement de production de mettre l’ensemble des données du fichier CSV dans une base de donnée afin de diminuer le temps d’exécution du script de localisation.
Nous avons tous les éléments nécessaires, il suffit maitenant d’appeller les fonctions dans le bon ordre:
Ce qui donne:
// 1. Recuperation de l'addresse IP $ip = $_SERVER['REMOTE_ADDR'] ; // 2. Obtention du Numero Ip associe $ipnum = generer_num_ip( $ip ); // 3. Obtention du Pays associe a ce Numero Ip $country = process_csv ( 'GeoIPCountryWhois.csv', $ipnum); // 4. Affichage du Resultat echo"Votre Pays: <b>$country</b> ";
function generer_num_ip($addr_ip)
{
$decomposition = preg_split( "/[.]+/", $addr_ip);
$numip = (double) (16777216*$decomposition[0] + 65536*$decomposition[1] + 256*$decomposition[2] + $decomposition[3]);
return( $numip );
}
function process_csv($file, $ipnum)
{
// Ouvrir le fichier
$handle = fopen($file, "r");
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE)
{ // Pour Chaque Ligne Lu
if( ($ipnum >= $data[2]) &&
($ipnum <= $data[3]) )
{
// Sortir du while
break;
}
}
fclose($handle);
return $data[5];
}
// Enregistrement du Timestamp avant execution du script
$start_time = microtime(true);
// Recuperation de l'addresse IP
$ip = $_SERVER['REMOTE_ADDR'] ;
// Affichage de l'Addrese IP
echo"<br><br>Votre IP est: <b> $ip </b><br><br>";
// Obtention du Numero Ip associe
$ipnum = generer_num_ip( $ip );
// Affichage du Numero Ip associe
echo"Numero IP associe: $ipnum<br><br>";
// Obtention du Pays associe a ce Numero Ip
$country = process_csv ( 'GeoIPCountryWhois.csv', $ipnum);
// Affichage du Pays
echo"Votre Pays: <b>$country</b> <br><br>";
// Enregistrement du Timestamp apres execution du script
$stop_time = microtime(true);
// Cacul de la duree d'execution du script en Milisecondes
$duration = 1000*($stop_time - $start_time);
echo "Temps d'execution du script: <b>$duration ms</b> ";
4 Responses
Joris
22|Oct|2009 1Bonjour,
là franchement je dois avoué que c’est une très très bonne initiative.
Ton tuto est très bien expliqué, facile à comprendre.
Depuis, j’utilise moi même ce système pour mes sites.
Bonne journée et bonne continuation.
nandato
08|Nov|2009 2génial, un grand merci pour ce petit tuto qui marche impecc’ !
david
26|Nov|2009 3Bonjour,
Excellent, je l’utilise grave, par contre ça serait kool de nous faire le même tuto mais cette fois-ci avec le fichier csv en bdd mysql…
Encore bravo pour la clarté de cet article !!!!
C’est un réel plaisir,
David
Chris
27|Nov|2009 4Merci Merci.
Un screencast avec stockage des plages IP dans une base de donnée est prevu… Reste a trouver un peu de temps pour le faire ;)
Leave a reply