Developpez.com

PHP

Choisissez la catégorie, puis la rubrique :

 

Connaître le pays d'un visiteur
en fonction de son adresse IP

Dernière mise à jour : 15 mai 2003

Par Hugo ETIEVANT (cyberzoide)

Téléchargez la version PDF (269 Ko)

  1. Généralités
  2. Le WebService IP-to-Country
    1. Format du nom du pays
    2. Format de l'adresse IP
    3. Exemple
    4. Limites du service web
  3. La base de données de IP-to-Country
    1. Téléchargement
    2. Structure de la base
    3. Exemple
    4. Interrogation
    5. Noms en français
  4. Limites de cette méthode
  5. Alternatives
  6. Conclusion

Généralités

Internet est connu pour être un espace de liberté où l'on peut surfer anonymement.

Depuis quelques années, le commerce électronique connaît un fort développement et la pub en ligne est une source de revenus importante. Les publicitaires déploient beaucoup d'efforts pour profiler les visiteurs, mais avec une efficacité toute relative. Le pays de provenance des visiteurs est ainsi une information stratégique pour mieux analyser la fréquentation d'un site, pour savoir dans quelle langue afficher une publicité...

logo de Directi

La société Directi - société d'enregistrement de noms de domaines accréditée par l'ICANN - propose un service nommé Ip-to-country qui permet de connaître le pays d'origine d'un internaute en fonction de son adresse IP. Son offre gratuite se décline en deux volets :

  • un service web interactif
  • une base de données à télécharger

logo de Directi

Ce service est fiable à 98% et permet d'offrir les fonctionnalités suivantes :

  • formater correctement les données (monnaies, nombres, dates...)
  • ciblage publicitaire
  • internationalisation des pages
  • détection de fraude à la carte bancaire
  • gestion des droits d'accès
  • géo-localisation des visiteurs
  • etc.

Le WebService IP-to-Country

Un web service ("service web" en français) est un service en ligne distant géré par une société et interagissant avec les scripts de n'importe quel autre site web.

On peut demander au site htpp://www.ip-to-country.com le pays correspondant à une IP via la méthode GET du protocole HTTP. Cette connexion requiert une authentification avec l'identifiant guest et le mot de passe guest.

Pour effectuer cette requète en PHP, il faut procéder ainsi :

  1. ouvrir une socket avec fsockopen()
  2. envoyer la requête au travers de la socket avec fputs()
  3. et lire avec fgets() le résultat retourné par le serveur

La socket doit être ouverte sur le serveur www.ip-to-country.com et la requète se décompose en la directive GET sur la ressource "/get-country/?ip=".$ip2."&user=guest&pass=guest$ip2 est l'adresse IP traduite en un nombre unique (sans les points de séparation des 4 champs codés sur 8 bits) et l'autre directive Host rappelant le domaine du serveur : ip-to-country.com.

Exemple :

<?php
    
/* extraction adresse IP du visiteur */
    
$ip $_SERVER['REMOTE_ADDR'];
    
/* transformation IP */
    
$dotted preg_split"/[.]+/"$ip);
    
$ip2 = (double) ($dotted[0]*16777216)+($dotted[1]*65536)+($dotted[2]*256)+($dotted[3]);    
    
/* URL du serveur et paramètres à lui passer */
    
$url "/get-country/?ip=".$ip2."&user=guest&pass=guest";
    
/* ouverture de la socket */
    
$fp fsockopen ("www.ip-to-country.com"80, &$errno, &$errstr30);
    
/* test si erreur à l'ouverture */
    
if (!$fp) {
        
/* affichage de l'erreur */
        
echo "$errstr ($errno)<br>\n";
    } else {
        
/* envoi de la requête HTTP */
        
fputs ($fp"GET $url HTTP/1.0\r\nHost: ip-to-country.com\r\n\r\n");
        
/* réception des données en retour */
        
while (!feof($fp)) {
            
/* extraction réponse */
            
$response .= fgets ($fp,128);
        }
        
/* fermeture socket */
        
fclose ($fp);
    }
?>

Format du nom du pays

logo de ISO

Le résultat renvoyé par le serveur ip-to-country.com est le code ISO-3166 du pays associé à l'adresse IP soumise. Ce code correspond à une norme internationale définie par l'International Organization for Standardization (aller directement à la page norme ISO-3166 en français).

"Ces noms de pays sont ceux notifiés officiellement par les pays concernés au Secrétaire général de l'ONU. Cette origine permet de préserver la neutralité politique de la norme et est l'un des facteurs déterminants de l'acceptation mondiale que connaît aujourd'hui l'ISO 3166.", ISO.ch.

Format de l'adresse IP

L'adresse IP doit être transformée en un nombre avant d'être envoyée au serveur ip-to-country.com car les points sont des caractères spéciaux qui ne peuvent être envoyés directement dans l'URL, pour cela utiliser la fonction de transformation ci-bas. Une adresse IP est de la forme A.B.C.D, le nombre correspondant est de la forme : A * (256*256*256) + B * (256*256) + C * 256 + D.

<?php
    
function IPAddress2IPNumber($dotted) {
        
$dotted preg_split"/[.]+/"$dotted);
        
$ip = (double) ($dotted[0]*16777216)+($dotted[1]*65536)+($dotted[2]*256)+($dotted[3]);
        return 
$ip;
    }
?>

La fonction inverse permettant de revenir à la forme avec des points est la suivante :

<?php
    
function IPNumber2IPAddress($number) {
        
$a = ($number/16777216)%256;
        
$b = ($number/65536)%256;
        
$c = ($number/256)%256;
        
$d = ($number)%256;
        
$dotted $a.".".$b.".".$c.".".$d;
        return 
$dotted;
    }
?>

Exemple

Suite à la requête, voici ce que retourne le serveur :

HTTP/1.1 200 OK
Date: Mon, 19 May 2003 06:28:46 GMT
Server: Apache/1.3.22 (Unix)  (Red-Hat/Linux) PHP/4.0.4pl1
X-Powered-By: PHP/4.0.4pl1
Connection: close
Content-Type: text/html

France
dont il faut extraire le nom du pays, c'est facile c'est la dernière ligne qu'on extrait de la façon suivante :
<?php
    $lignes 
explode("\n",$response);
    
$pays $lignes[sizeof($lignes)-1];
?>

Exemple : d'après votre adresse IP 81.48.177.151 transformée en 1362145687, votre pays d'origine est : France

Limites du service web

Utiliser le service web implique de pouvoir utiliser les sockets, ce que la configuration de votre serveur ne permet peut-être pas. De plus, en cas d'interruption de service du serveur ip-to-country.com ou bien d'aléas dans les performances du réseau vers les Etats-Unis (où est localisé leur serveur), il n'est plus possible de déterminer le pays d'un visiteur.

De plus, il peut être préférable pour des raisons de performances (ou autres) d'avoir sur son propre serveur toutes les données nécessaires à la résolution du nom de pays des visiteurs.

Pour toutes ces raisons il peut s'avérer utile de télécharger la base de données de ip-to-contry.com

Mise à jour (03 juillet 2010) : le service n'est temporairement plus accessible en ligne, il reste donc le mode local à exploiter.

La base de données de IP-to-Country

Téléchargement

Le site ip-to-country.com propose aussi de télécharger sa base de données au format CSV (fichier texte dont le séparateur de champs est la virgule, le séparateur de ligne \n et les champs sont encadrés par des doubles quotes). Dont une copie miroir se trouve ici : March-2003.zip (161 ko).

Structure de la base

Cette base de données est constituée d'une table associant un pays à des plages d'adresses IP. Ces adresse IP sont codées en un nombre comme vu plus haut. Les pays sont identifiés par leur code sur deux lettres ainsi que leur nom complet anglais dans la norme ISO-3166.

La structure de la table de la base est la suivante :

CREATE TABLE `ip-to-country` (
	`IP_FROM` DOUBLE NOT NULL, 
	`IP_TO` DOUBLE NOT NULL, 
	`COUNTRY_CODE` CHAR(2), 
	`COUNTRY_NAME` VARCHAR(50),
	PRIMARY KEY(`IP_FROM`,`IP_TO`)
)

Exemple

Voici quelques lignes de cette table :

IP_FROMIP_TOCOUNTRY_CODECOUNTRY_NAME
10422845441042292735CHSWITZERLAND
10422927361042317311UKUNITED KINGDOM
10423173121042350079PLPOLAND
10423500801042415615RURUSSIAN FEDERATION
10424156161042546687FRFRANCE
10425466881042677759ESSPAIN
10426777601042743295GRGREECE
10427432961042808831FRFRANCE
10428088321042817023DEGERMANY
10428170241042825215IEIRELAND
10428252161042833407CZCZECH REPUBLIC

Ainsi la plage des adresses de 62.32.0.0 (codée en 1042284544) à 62.32.31.255 (codée en 1042292735) correspondent à la Suisse (SWITZERLAND).

Interrogation

L'interrogation en language SQL est relativement simple, voici un exemple de requète :

SELECT `COUNTRY_NAME` 
FROM `ip-to-country` 
WHERE $ip2 BETWEEN `IP_FROM` AND `IP_TO`
$ip2 est l'adresse IP du visiteur codée numériquement.

Noms en français

Dans la norme ISO-3166, les noms de pays sont en anglais, le site iso.ch permet de télécharger les noms en français, ce qui permet de modifier la base de données afin d'afficher le nom du pays en français.

Limites de cette méthode

Cette méthode se base exclusivement sur l'adresse IP qu'utilise le visiteur pour se connecter à Internet. Or les grands groupes mondiaux centralisent bien souvent leurs accès au Net par continents sur un seul site auquel sont reliées toutes les machines du groupe. Et c'est ainsi une seule et même plage d'adresses IP qui est répartie entre toutes les machines connectées de plusieurs pays. Alors notre méthode tombe à l'eau car le pays d'origine ainsi déterminé est celui de la connexion unique centralisée et pas celui de la machine cliente.

Alternatives

Il existe d'autres moyens de connaître le pays d'origine de l'internaute, par exemple, la variable d'environnement $_SERVER["HTTP_ACCEPT_LANGUAGE"] du serveur retourne la langue du client, qui dépend de la configuration du navigateur de l'internaute (donnée non fiable). Cet artifice ne permet pas - en revanche - de distinguer le visiteur parlant anglais connecté depuis une machine en Angleterre ou depuis son hôtel au Congo...

Conclusion

Cette méthode offerte par "IP to Country" de Directi permet sans doute de déterminer le pays d'origine de l'internaute dans la majorité des cas, mais certaines plages minoritaires d'adresses IP ne sont pas référencées ou ne permettent pas de connaître le pays réel d'origine. Cependant, en l'absence d'autre solution plus fiable, ce service semble un outil utile et performant.

Remerciements à Youri.ch et à jérôme pour leurs remarques constructives ; ainsi qu'à stessy et à Alacazam pour la correction orthographique.

Date de première publication : 15 mai 2003
Date de dernière modification : 15 mai 2003
Titre original : Connaître le pays d'un visiteur en fonction de son adresse IP
Auteur : Hugo Etiévant - cyberzoide at yahoo dot fr
URL originale : http://cyberzoide.developpez.com/php4/ip-to-country/index.php3
Tous droits de reproduction réservés. Toute copie de ce document doit faire l'objet d'une autorisation écrite préalable.

Contacter le responsable de la rubrique PHP