Sommaire:

Problematique:

  • Comment savoir d’ou viennent mes visiteurs?
  • Comment diffuser de la publicité en fonction de la localisation d’un visiteur?
  • Comment bloquer un visiteur en fonction de son pays? …

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.

http://blip.tv/file/get/Formatix-phpLocalisationAddresseIPVisiteurfrdivX886.flv

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.

Adresse IP

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>';

Localisation de l’IP

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:

  • GeoLite (Gratuit)
  • GeoIP(Payante)

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.

  • ‘2.6.190.56′,’2.6.190.63′,’33996344′,’33996351′,’GB’,'United Kingdom’
  • ‘3.0.0.0′,’4.17.135.31′,’50331648′,’68257567′,’US’,'United States’
  • ‘4.17.135.32′,’4.17.135.63′,’68257568′,’68257599′,’CA’,'Canada’
  • ‘4.17.135.64′,’4.17.142.255′,’68257600′,’68259583′,’US’,'United States’
  • ‘4.17.143.0′,’4.17.143.15′,’68259584′,’68259599′,’CA’,'Canada’
  • ‘4.17.143.16′,’4.18.32.71′,’68259600′,’68296775′,’US’,'United States’
  • ‘4.18.32.72′,’4.18.32.79′,’68296776′,’68296783′,’MX’,'Mexico’
  • ‘4.18.32.80′,’4.18.40.135′,’68296784′,’68298887′,’US’,'United States’
  • ‘4.18.40.136′,’4.18.40.143′,’68298888′,’68298895′,’CA’,'Canada’

Comme vous pouvez le voir chaque ligne est constituée de 6 ‘champs’:

  • Adresse IP de Départ
  • Adresse IP de Fin
  • Numéro IP de Départ
  • Numéro IP de Fin
  • Identifiant de Pays ISO 3166
  • Nom du Pays

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

Transformation IP en Numéro IP

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 );

}

Exploration du fichier CSV de Geolocalisation

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:

  • Ouvrir le fichier CSV
  • Lire chaque ligne
  • S’arrêter si le Numéro IP est contenu dans la plage [Numéro IP de Départ -Numéro IP de Fin] de la ligne lu
  • Récupérer le champs Pays de cette ligne

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.

Geolocalisation proprement dite

Nous avons tous les éléments nécessaires, il suffit maitenant d’appeller les fonctions dans le bon ordre:

  1. Trouver l’addresse IP du visiteur
  2. Transformer cette address en Numero IP
  3. Scanner le fichier CVS afin d’obtenir le pays associe

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> ";

Script Complet


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> ";