Archives du tag ◊ localisation ◊

Auteur : cyrilpop
• 7 novembre 2008 20:27
  • Présentation

Salut à tous, on m’a demandé plusieurs fois comment j’ai réussi « l’exploit » de trouver la ville d’une personne qui visite votre site internet. Ça se passe en plusieurs étapes.

Déjà un pré-requis est d’avoir un serveur dédié pour optimiser les choses…

Il y a un site très intéressant qui regroupe toutes les IP et à quelle ville cela correspond. Donc une fois la correspondance trouvée il suffit de récupérer l’IP du visiteur et le tour est joué… Enfin presque.

  • Préparation de la base de données

Dans un premier temps il faut récupérer le fichier et l’entrer dans sa base de données. Créer les tables avec la requête suivante :

  1. – Structure de la table `City_Block`
  2.  
  3. CREATE TABLE `City_Block` (
  4. `startIpNum` bigint(10) NOT NULL,
  5. `endIpNum` bigint(10) NOT NULL,
  6. `locId` bigint(10) NOT NULL
  7. ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
  8. – ——————————————————–
  9.  
  10. – Structure de la table `City_Location`
  11.  
  12. CREATE TABLE `City_Location` (
  13. `locId` bigint(10) NOT NULL,
  14. `country` varchar(2) NOT NULL,
  15. `region` varchar(2) NOT NULL,
  16. `city` varchar(50) NOT NULL,
  17. `postalCode` varchar(5) NOT NULL,
  18. `latitude` varchar(7) NOT NULL,
  19. `longitude` varchar(7) NOT NULL,
  20. `metroCode` varchar(5) NOT NULL,
  21. `areaCode` varchar(5) NOT NULL,
  22. PRIMARY KEY (`locId`)
  23. ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
  • Remplissage de la base de données
  • Pour intégrer le fichier dans sa base de données écrire le script suivant.

    1. LOG=/log/geoip.log
    2. echo "" >>; $LOG
    3. echo "Debut du remplissage `date`">>$LOG
    4. DATE=`date +%Y%m`
    5. adresse=http://www.maxmind.com/download/geoip/database/GeoLiteCity_CSV/
    6. cd /tmp
    7. wget http://www.maxmind.com/download/geoip/database/GeoLiteCity_CSV/
    8. fic=`cat index.html | grep zip | cut -d\" -f6 | tail -1`
    9. rm index.html
    10. wget $adresse/$fic
    11. unzip $fic
    12. rm $fic
    13. cd GeoLiteCity*
    14. pwd
    15. sed -e s/\"//g GeoLiteCity-Blocks.csv > GeoLiteCity-Blocks.tmp && mv -f GeoLiteCity-Blocks.tmp GeoLiteCity-Blocks.csv
    16. sed -e s/\"//g GeoLiteCity-Location.csv > GeoLiteCity-Location.tmp &&  mv -f GeoLiteCity-Location.tmp GeoLiteCity-Location.csv
    17. mysql -uUSER -pPASSWD < < EOF
    18. use geoip
    19. TRUNCATE TABLE City_Block;
    20. TRUNCATE TABLE City_Location;
    21. LOAD DATA LOCAL INFILE ‘GeoLiteCity-Blocks.csv’
    22. INTO TABLE City_Block
    23. FIELDS TERMINATED BY ‘,’
    24. LINES TERMINATED BY ‘\n‘;
    25.  
    26. LOAD DATA LOCAL INFILE ‘GeoLiteCity-Location.csv’
    27. INTO TABLE City_Location
    28. FIELDS TERMINATED BY ‘,’
    29. LINES TERMINATED BY ‘\n‘;
    30. exit
    31. EOF
    32. echo "—–Nombres d‘entrees pour les blocks : `wc -l GeoLiteCity-Blocks.csv`">>$LOG
    33. echo "Fin du remplissage `date`">>$LOG
    34. echo "–nb d entrees pour les vilels : `wc -l GeoLiteCity-Location.csv`">> $LOG
    35. cd /tmp
    36. rm -rf GeoLiteCity*
    37. echo "Fin du traitement `date`"

    Le fichier est mis à jour une fois par mois. Vous pouvez donc intégrer le script dans votre crontab. Personnellement j’ai essayé de le faire le 2 du mois mais il y a eu comme un bug, du coup je le fais le 5 du mois et ca marche très bien :)

    • Intégration dans une page internet

    C’est bien joli d’avoir une belle base de données, mais encore faut-il pouvoir l’utiliser. Le principe de fonctionnement de la base est qu’une ip qui s’ecrit normalement en 10.2.5.9 s’écrit en un seul chiffre. Comment est-ce possible ? Tout simplement en utilisant une base 256… Et oui de 0 à 255 ca fait bien 256 chiffres; Je vous passe la conversion mais c’est le même principe que les conversions hexa, binaire… Ensuite comme les donnes fonctionne par plage il suffit de trouver à quelle plage appartient notre IP et le tour est joué.
    Voici donc le code qu’il faut inclure dans votre page web :

    1. < ?php
    2. //*********************************************************
    3. // Retourne l’adresse IP du visiteur
    4. //*********************************************************
    5. function get_Ip() {
    6.         if(isset($_SERVER[‘HTTP_X_FORWARDED_FOR’])) {
    7.                 $ip = $_SERVER[‘HTTP_X_FORWARDED_FOR’];
    8.         }
    9.         elseif(isset($_SERVER[‘HTTP_CLIENT_IP’])) {
    10.                 $ip  = $_SERVER[‘HTTP_CLIENT_IP’];
    11.         }
    12.         else {
    13.                 $ip = $_SERVER[‘REMOTE_ADDR’];
    14.         }
    15.         return $ip;
    16.  }
    17.  
    18.  
    19.  //*********************************************************
    20.  // fonction qui ransforme l’IP en nombre
    21.  //*********************************************************
    22.  function IPAddress2IPNumber($dotted)
    23. {
    24.         $dotted = preg_split( "/[.]+/", $dotted);
    25.         $ip = (double) ($dotted[0]*16777216)+($dotted[1]*65536)+($dotted[2]*256)+($dotted[3]);
    26.         return $ip;
    27.  }
    28.  
    29. //***************************************
    30. //Fonction pour avoir la ville
    31. //**************************************
    32. function IpEnVille($uneIp)
    33.  {
    34.  
    35.                 $db = mysql_connect(‘localhost’, ‘root’, ‘mot_de_passe’);
    36.                 mysql_select_db(‘brikole’,$db);
    37.  
    38.                 // transforme l’ip en nombre
    39.                 $uneIp=IPAddress2IPNumber($uneIp);
    40.  
    41.                 $sql_locId ="SELECT City_Block.locId  FROM City_Block WHERE ‘".$uneIp."’ BETWEEN startIpNum AND endIpNum ";
    42.                 $req = mysql_query($sql_locId);
    43.                 $data = mysql_fetch_assoc($req);
    44.                 $retour=$data[locId];
    45.                 $locId=$retour;
    46.  
    47.                 $sql_city = "SELECT City_Location.city FROM City_Location WHERE locId     = ‘".$locId         ."’;";
    48.                 $req = mysql_query($sql_city);
    49.                 $data_city = mysql_fetch_assoc($req);
    50.                 $city=$data_city[city];
    51.                 mysql_close();
    52.  
    53.                 return $city;
    54. }

    Ensuite il suffit d’appeler la fonction de cette facon

    1. IpEnVille(Get_Ip());

    Voilà, si vous avez des questions n'hésitez pas... Mais en suivant step by step ca devrait aller tout seul ;)