web-dev-qa-db-fra.com

Obtenir la localisation d'une adresse IP

Je souhaite récupérer des informations telles que la ville, l'état et le pays d'un visiteur à partir de son adresse IP, afin de pouvoir personnaliser ma page Web en fonction de son emplacement. Existe-t-il un moyen fiable et efficace de faire cela en PHP? J'utilise JavaScript pour les scripts côté client, PHP pour les scripts côté serveur et MySQL pour la base de données.

190
krishna Kant

Vous pouvez télécharger une base de données GeoIP gratuite et rechercher l'adresse IP localement, ou vous pouvez utiliser un service tiers et effectuer une recherche à distance. C'est l'option la plus simple, car elle ne nécessite aucune configuration, mais introduit une latence supplémentaire.

Un service tiers que vous pouvez utiliser est le mien, http://ipinfo.io . Ils fournissent le nom d’hôte, la géolocalisation, le propriétaire du réseau et des informations supplémentaires, par exemple:

$ curl ipinfo.io/8.8.8.8
{
  "ip": "8.8.8.8",
  "hostname": "google-public-dns-a.google.com",
  "loc": "37.385999999999996,-122.0838",
  "org": "AS15169 Google Inc.",
  "city": "Mountain View",
  "region": "CA",
  "country": "US",
  "phone": 650
}

Voici un exemple PHP:

$ip = $_SERVER['REMOTE_ADDR'];
$details = json_decode(file_get_contents("http://ipinfo.io/{$ip}/json"));
echo $details->city; // -> "Mountain View"

Vous pouvez également l'utiliser côté client. Voici un exemple simple de jQuery:

$.get("https://ipinfo.io/json", function (response) {
    $("#ip").html("IP: " + response.ip);
    $("#address").html("Location: " + response.city + ", " + response.region);
    $("#details").html(JSON.stringify(response, null, 4));
}, "jsonp");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h3>Client side IP geolocation using <a href="http://ipinfo.io">ipinfo.io</a></h3>

<hr/>
<div id="ip"></div>
<div id="address"></div>
<hr/>Full response: <pre id="details"></pre>
233
Ben Dowling

Je pensais que je posterais car personne ne semble avoir donné d’informations sur cette API particulière, mais elle renvoie exactement ce que je recherche et vous pouvez l’obtenir dans plusieurs formats, json, xml and csv.

 $location = file_get_contents('http://freegeoip.net/json/'.$_SERVER['REMOTE_ADDR']);
 print_r($location);

Cela vous donnera toutes les choses que vous pourriez souhaiter:

{
      "ip": "77.99.179.98",
      "country_code": "GB",
      "country_name": "United Kingdom",
      "region_code": "H9",
      "region_name": "London, City of",
      "city": "London",
      "zipcode": "",
      "latitude": 51.5142,
      "longitude": -0.0931,
      "metro_code": "",
      "areacode": ""

}
57
Jamie Hutber

Utilisation de Google APIS:

<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script>
contry_code = google.loader.ClientLocation.address.country_code
city = google.loader.ClientLocation.address.city
region = google.loader.ClientLocation.address.region
</script>
15
Raposo

Vous devez utiliser un service externe ... tel que http://www.hostip.info/ Si vous recherchez Google pour "geo-ip", vous pouvez obtenir plus de résultats.

L'API Host-IP est basée sur HTTP. Vous pouvez donc l'utiliser en PHP ou en JavaScript, selon vos besoins.

15
null

J'ai écrit un bot en utilisant une API de ipapi.co , voici comment vous pouvez localiser une adresse IP (par exemple 1.2.3.4) dans php:

Définir l'en-tête:

$opts = array('http'=>array('method'=>"GET", 'header'=>"User-Agent: mybot.v0.7.1"));
$context = stream_context_create($opts);

Obtenir une réponse JSON

echo file_get_contents('https://ipapi.co/1.2.3.4/json/', false, $context);

d'obtenir un champ spécifique (pays, fuseau horaire, etc.)

echo file_get_contents('https://ipapi.co/1.2.3.4/country/', false, $context);
14
Jaimes

Un pur exemple Javascript, utilisant les services de https://geoip-db.com Ils fournissent une solution de rappel JSON et JSONP.

Pas besoin de jQuery!

<!DOCTYPE html>
<html>
<head>
<title>Geo City Locator by geoip-db.com</title>
</head>
<body>
    <div>Country: <span id="country"></span></div>
    <div>State: <span id="state"></span></div>
    <div>City: <span id="city"></span></div>
    <div>Postal: <span id="postal"></span></div>
    <div>Latitude: <span id="latitude"></span></div>
    <div>Longitude: <span id="longitude"></span></div>
    <div>IP address: <span id="ipv4"></span></div>                             
</body>
<script>

    var country = document.getElementById('country');
    var state = document.getElementById('state');
    var city = document.getElementById('city');
    var postal = document.getElementById('postal');
    var latitude = document.getElementById('latitude');
    var longitude = document.getElementById('longitude');
    var ip = document.getElementById('ipv4');

    function callback(data)
    {
        country.innerHTML = data.country_name;
        state.innerHTML = data.state;
        city.innerHTML = data.city;
        postal.innerHTML = data.postal;
        latitude.innerHTML = data.latitude;
        longitude.innerHTML = data.longitude;
        ip.innerHTML = data.IPv4;
    }

    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'https://geoip-db.com/json/geoip.php?jsonp=callback';
    var h = document.getElementsByTagName('script')[0];
    h.parentNode.insertBefore(script, h);

</script> 
</html>
14

Cette question est protégée, ce que je comprends. Cependant, je ne vois pas de réponse ici, ce que je vois, c’est que beaucoup de gens montrent ce qui leur est arrivé en posant la même question.

Il existe actuellement cinq registres Internet régionaux dotés de fonctionnalités différentes qui servent de premier point de contact en ce qui concerne la propriété intellectuelle. Le processus est en mutation, raison pour laquelle les différents services ici fonctionnent parfois et ne fonctionnent pas à d'autres moments.

Who Is est (évidemment) un ancien protocole TCP, cependant - la façon dont cela fonctionnait à l’origine était de se connecter au port 43, ce qui rend difficile le routage de celui-ci via des connexions louées, des pare-feu, etc.

En ce moment - la plupart des utilisateurs sont créés via HTTP RESTful et ARIN, RIPE et APNIC disposent de services RESTful qui fonctionnent. LACNIC renvoie 503 et AfriNIC ne dispose apparemment pas d'une telle API. (Tous ont des services en ligne, cependant.)

Vous obtiendrez ainsi - l'adresse du propriétaire enregistré de l'IP, mais - et non l'emplacement de votre client - vous devez l'obtenir de sa part et aussi - vous devez le demander. En outre, les mandataires sont le moindre de vos soucis lors de la validation de l’IP que vous pensez être l’initiateur.

Les gens n'apprécient pas l'idée de faire l'objet d'un suivi, alors, pense-t-il, l'obtenez directement auprès de votre client, avec sa permission, et attendez-vous beaucoup à vous en vouloir.

9
jinzai

Regardez l'API de hostip.info - elle fournit de nombreuses informations.
Exemple en PHP:

$data = file_get_contents("http://api.hostip.info/country.php?ip=12.215.42.19");
//$data contains: "US"

$data = file_get_contents("http://api.hostip.info/?ip=12.215.42.19");
//$data contains: XML with country, lat, long, city, etc...

Si vous faites confiance à hostip.info, cela semble être une API très utile.

8
Isaac Waller

En supposant que vous souhaitiez le faire vous-même et ne pas vous fier à d’autres fournisseurs, IP2Nation fournit une base de données MySQL des mappages qui sont mis à jour à mesure que les registres régionaux changent.

7
James Cape

J'aime la version gratuite GeoLite City de Maxmind qui fonctionne pour la plupart des applications et à partir de laquelle vous pouvez passer à une version payante si elle n’est pas assez précise. Il y a un API PHP inclus, ainsi que pour d'autres langages. Et si vous utilisez Lighttpd en tant que serveur Web, vous pouvez même utiliser un module pour obtenir les informations de la variable SERVER pour chaque visiteur si vous en avez besoin.

J'ajouterais qu'il existe également un programme Geolite Country (qui serait plus rapide si vous n'avez pas besoin d'indiquer la ville d'origine de l'adresse IP) et Geolite ASN (si vous souhaitez savoir à qui appartient cette propriété ) et que finalement tous ceux-ci sont téléchargeables sur votre propre serveur, sont mis à jour tous les mois et sont assez rapides à consulter avec les API fournies car elles indiquent "des milliers de recherches par seconde".

7
lpfavreau

PHP a un extension pour cela.

De PHP.net:

L'extension GeoIP vous permet de trouver l'emplacement d'une adresse IP. L’aide de GeoIP permet d’obtenir des informations sur la ville, l’État, le pays, la longitude, la latitude et d’autres informations, telles que le type de fournisseur d’accès Internet et le type de connexion.

Par exemple:

$record = geoip_record_by_name($ip);
echo $record['city'];
6
Ian Hunter

Le service dans la réponse de Ben Dowling a changé, il est donc maintenant plus simple. Pour trouver l'emplacement, faites simplement:

// no need to pass ip any longer; ipinfo grabs the ip of the person requesting
$details = json_decode(file_get_contents("http://ipinfo.io/"));
echo $details->city; // city

Les coordonnées retournent en une seule chaîne comme '31, -80 ', à partir de là, il vous suffit de:

$coordinates = explode(",", $details->loc); // -> '31,-89' becomes'31','-80'
echo $coordinates[0]; // latitude
echo $coordinates[1]; // longitude
6
Isaac Askew

Ipdata.co est une API de géolocalisation IP rapide, à haute disponibilité et aux performances fiables.

Il est extrêmement évolutif, avec 10 terminaux dans le monde, chacun capable de traiter plus de 10 000 requêtes par seconde!

Cette réponse utilise une clé d'API 'test' très limitée et destinée uniquement à tester quelques appels. Signup pour votre propre clé API gratuite et recevez jusqu'à 1500 requêtes de développement par jour.

En php

php > $ip = '8.8.8.8';
php > $details = json_decode(file_get_contents("https://api.ipdata.co/{$ip}?api-key=test"));
php > echo $details->region;
California
php > echo $details->city;
Mountain View
php > echo $details->country_name;
United States
php > echo $details->latitude;
37.751

Voici un exemple côté client montrant comment obtenir le pays, la région et la ville;

$.get("https://api.ipdata.co?api-key=test", function (response) {
        $("#response").html(JSON.stringify(response, null, 4));
  $("#country").html('Country: ' + response.country_name);
  $("#region").html('Region ' + response.region);
  $("#city").html('City' + response.city);  
}, "jsonp");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="country"></div>
<div id="region"></div>
<div id="city"></div>
<pre id="response"></pre>

Disclaimer;

J'ai construit le service.

Pour des exemples en plusieurs langues, voir Docs

Voir aussi this analyse détaillée des meilleures API de géolocalisation IP.

6
Jonathan

Au cas où quelqu'un trébucherait sur ce fil, voici une autre solution. Sur timezoneapi.io , vous pouvez demander une adresse IP et obtenir plusieurs objets en retour (j'ai créé le service). Il a été créé parce que j’avais besoin de savoir dans quel fuseau horaire étaient mes utilisateurs, où et dans le monde et à quelle heure il était.

Dans PHP - renvoie l'emplacement, le fuseau horaire et la date/heure:

// Get IP address
$ip_address = getenv('HTTP_CLIENT_IP') ?: getenv('HTTP_X_FORWARDED_FOR') ?: getenv('HTTP_X_FORWARDED') ?: getenv('HTTP_FORWARDED_FOR') ?: getenv('HTTP_FORWARDED') ?: getenv('REMOTE_ADDR');

// Get JSON object
$jsondata = file_get_contents("http://timezoneapi.io/api/ip/?" . $ip_address);

// Decode
$data = json_decode($jsondata, true);

// Request OK?
if($data['meta']['code'] == '200'){

    // Example: Get the city parameter
    echo "City: " . $data['data']['city'] . "<br>";

    // Example: Get the users time
    echo "Time: " . $data['data']['datetime']['date_time_txt'] . "<br>";

}

Utilisation de jQuery:

// Get JSON object
$.getJSON('https://timezoneapi.io/api/ip', function(data){

    // Request OK?
    if(data.meta.code == '200'){

        // Log
        console.log(data);

        // Example: Get the city parameter
        var city = data.data.city;
        alert(city);

        // Example: Get the users time
        var time = data.data.datetime.date_time_txt;
        alert(time);

    }

});
5
Michael Nilsson

Je lance le service sur IPLocate.io , auquel vous pouvez vous connecter gratuitement en un simple appel:

<?php
$res = file_get_contents('https://www.iplocate.io/api/lookup/8.8.8.8');
$res = json_decode($res);

echo $res->country; // United States
echo $res->continent; // North America
echo $res->latitude; // 37.751
echo $res->longitude; // -97.822

var_dump($res);

L'objet $res contient vos champs de géolocalisation tels que country, city, etc.

Consultez le docs pour plus d'informations.

5
ttarik

Voici une version modifiée d’un extrait que j’ai trouvé et qui utilise http://ipinfodb.com/ip_locator.php pour obtenir ses informations. N'oubliez pas que vous pouvez également demander une clé d'API avec eux et utiliser l'API directement pour obtenir les informations fournies à votre guise.

Fragment

function detect_location($ip=NULL, $asArray=FALSE) {
    if (empty($ip)) {
        if (!empty($_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; }
        elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; }
        else { $ip = $_SERVER['REMOTE_ADDR']; }
    }
    elseif (!is_string($ip) || strlen($ip) < 1 || $ip == '127.0.0.1' || $ip == 'localhost') {
        $ip = '8.8.8.8';
    }

    $url = 'http://ipinfodb.com/ip_locator.php?ip=' . urlencode($ip);
    $i = 0; $content; $curl_info;

    while (empty($content) && $i < 5) {
        $ch = curl_init();
        $curl_opt = array(
            CURLOPT_FOLLOWLOCATION => 1,
            CURLOPT_HEADER => 0,
            CURLOPT_RETURNTRANSFER  => 1,
            CURLOPT_URL => $url,
            CURLOPT_TIMEOUT => 1,
            CURLOPT_REFERER => 'http://' . $_SERVER['HTTP_Host'],
        );
        if (isset($_SERVER['HTTP_USER_AGENT'])) $curl_opt[CURLOPT_USERAGENT] = $_SERVER['HTTP_USER_AGENT'];
        curl_setopt_array($ch, $curl_opt);
        $content = curl_exec($ch);
        if (!is_null($curl_info)) $curl_info = curl_getinfo($ch);
        curl_close($ch);
    }

    $araResp = array();
    if (preg_match('{<li>City : ([^<]*)</li>}i', $content, $regs)) $araResp['city'] = trim($regs[1]);
    if (preg_match('{<li>State/Province : ([^<]*)</li>}i', $content, $regs)) $araResp['state'] = trim($regs[1]);
    if (preg_match('{<li>Country : ([^<]*)}i', $content, $regs)) $araResp['country'] = trim($regs[1]);
    if (preg_match('{<li>Zip or postal code : ([^<]*)</li>}i', $content, $regs)) $araResp['Zip'] = trim($regs[1]);
    if (preg_match('{<li>Latitude : ([^<]*)</li>}i', $content, $regs)) $araResp['latitude'] = trim($regs[1]);
    if (preg_match('{<li>Longitude : ([^<]*)</li>}i', $content, $regs)) $araResp['longitude'] = trim($regs[1]);
    if (preg_match('{<li>Timezone : ([^<]*)</li>}i', $content, $regs)) $araResp['timezone'] = trim($regs[1]);
    if (preg_match('{<li>Hostname : ([^<]*)</li>}i', $content, $regs)) $araResp['hostname'] = trim($regs[1]);

    $strResp = ($araResp['city'] != '' && $araResp['state'] != '') ? ($araResp['city'] . ', ' . $araResp['state']) : 'UNKNOWN';

    return $asArray ? $araResp : $strResp;
}

Utiliser

detect_location();
//  returns "CITY, STATE" based on user IP

detect_location('xxx.xxx.xxx.xxx');
//  returns "CITY, STATE" based on IP you provide

detect_location(NULL, TRUE);    //   based on user IP
//  returns array(8) { ["city"] => "CITY", ["state"] => "STATE", ["country"] => "US", ["Zip"] => "xxxxx", ["latitude"] => "xx.xxxxxx", ["longitude"] => "-xx.xxxxxx", ["timezone"] => "-07:00", ["hostname"] => "xx-xx-xx-xx.Host.name.net" }

detect_location('xxx.xxx.xxx.xxx', TRUE);   //   based on IP you provide
//  returns array(8) { ["city"] => "CITY", ["state"] => "STATE", ["country"] => "US", ["Zip"] => "xxxxx", ["latitude"] => "xx.xxxxxx", ["longitude"] => "-xx.xxxxxx", ["timezone"] => "-07:00", ["hostname"] => "xx-xx-xx-xx.Host.name.net" }
4
SpYk3HH

Si vous devez localiser une adresse IP, vous pouvez utiliser un service géo ip fiable, vous pouvez obtenir plus de détails ici . Il supporte IPv6.

En prime, il permet de vérifier si l'adresse IP est un nœud tor, un proxy public ou un spammeur.

Vous pouvez utiliser javascript ou php comme ci-dessous.

Code Javascript:

$(document).ready(function () {
        $('#btnGetIpDetail').click(function () {
            if ($('#txtIP').val() == '') {
                alert('IP address is reqired');
                return false;
            }
            $.getJSON("http://ip-api.io/json/" + $('#txtIP').val(),
                 function (result) {
                     alert('City Name: ' + result.city)
                     console.log(result);
                 });
        });
    });

Code php:

$result = json_decode(file_get_contents('http://ip-api.io/json/64.30.228.118'));
var_dump($result);

Sortie:

{
"ip": "64.30.228.118",
"country_code": "US",
"country_name": "United States",
"region_code": "FL",
"region_name": "Florida",
"city": "Fort Lauderdale",
"Zip_code": "33309",
"time_zone": "America/New_York",
"latitude": 26.1882,
"longitude": -80.1711,
"metro_code": 528,
"suspicious_factors": {
"is_proxy": false,
"is_tor_node": false,
"is_spam": false,
"is_suspicious": false
}
4
Vindhyachal Kumar

J'ai créé n wrapper pour ipinfo.io . Vous pouvez l'installer en utilisant composer.

Vous pouvez l'utiliser de cette façon:

$ipInfo = new DavidePastore\Ipinfo\Ipinfo();

//Get all the properties
$Host = $ipInfo->getFullIpDetails("8.8.8.8");

//Read all the properties
$city = $Host->getCity();
$country = $Host->getCountry();
$hostname = $Host->getHostname();
$ip = $Host->getIp();
$loc = $Host->getLoc();
$org = $Host->getOrg();
$phone = $Host->getPhone();
$region = $Host->getRegion();
3
Davide Pastore

J'ai effectué de nombreux tests avec les services d'adresse IP et voici quelques manières de le faire moi-même. Tout d’abord, quelques liens vers des sites utiles que j’utilise:

https://db-ip.com/db Dispose d'un service de recherche ip gratuit et de quelques fichiers csv gratuits à télécharger. Cela utilise une clé api gratuite jointe à votre courrier électronique. Il limite à 2000 requêtes par jour.

http://ipinfo.io/ Service de recherche ip gratuit sans clé d'api PHP:

//uses http://ipinfo.io/.
function ip_visitor_country($ip){
    $ip_data_in = get_web_page("http://ipinfo.io/".$ip."/json"); //add the ip to the url and retrieve the json data
    $ip_data = json_decode($ip_data_in['content'],true); //json_decode it for php use

    //this ip-lookup service returns 404 if the ip is invalid/not found so return false if this is the case.
    if(empty($ip_data) || $ip_data_in['httpcode'] == 404){
        return false;
    }else{
        return $ip_data; 
    }
}

function get_web_page($url){
    $user_agent = 'Mozilla/5.0 (Windows NT 6.1; rv:8.0) Gecko/20100101 Firefox/8.0';

    $options = array(
        CURLOPT_CUSTOMREQUEST  =>"GET",        //set request type post or get
        CURLOPT_POST           =>false,        //set to GET
        CURLOPT_USERAGENT      => $user_agent, //set user agent
        CURLOPT_RETURNTRANSFER => true,     // return web page
        CURLOPT_HEADER         => false,    // don't return headers
        CURLOPT_FOLLOWLOCATION => true,     // follow redirects
        CURLOPT_ENCODING       => "",       // handle all encodings
        CURLOPT_AUTOREFERER    => true,     // set referer on redirect
        CURLOPT_CONNECTTIMEOUT => 120,      // timeout on connect
        CURLOPT_TIMEOUT        => 120,      // timeout on response
        CURLOPT_MAXREDIRS      => 10,       // stop after 10 redirects
    );
    $ch = curl_init( $url );
    curl_setopt_array( $ch, $options );
    $content = curl_exec( $ch );
    $err     = curl_errno( $ch );
    $errmsg  = curl_error( $ch );
    $header  = curl_getinfo( $ch );
    $httpCode = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
    curl_close( $ch );  
    $header['errno']   = $err; //curl error code
    $header['errmsg']  = $errmsg; //curl error message
    $header['content'] = $content; //the webpage result (In this case the ip data in json array form)
    $header['httpcode'] = $httpCode; //the webpage response code
    return $header; //return the collected data and response codes
}

En fin de compte, vous obtenez quelque chose comme ceci:

Array
(
    [ip] => 1.1.1.1
    [hostname] => No Hostname
    [city] => 
    [country] => AU
    [loc] => -27.0000,133.0000
    [org] => AS15169 Google Inc.
)

http://www.geoplugin.com/ Légèrement plus ancien, mais ce service vous fournit de nombreuses informations utiles, telles que la devise du pays, le code du continent, la longitude, etc.


http://lite.ip2location.com/database-ip-country-region-city-latitude-longitude Offre un tas de fichiers téléchargeables avec les instructions pour les importer dans votre base de données. Une fois que vous avez placé ces fichiers dans votre base de données, vous pouvez les sélectionner assez facilement.

SELECT * FROM `ip2location_db5` WHERE IP > ip_from AND IP < ip_to

Utilisez la fonction php ip2long (); pour transformer l'adresse IP en une valeur numérique. Par exemple, 1.1.1.1 devient 16843009. Cela vous permet de rechercher les plages d'adresses IP qui vous sont données par le fichier de base de données.

Donc, afin de savoir à quel endroit 1.1.1.1 appartient à tout ce que nous faisons, nous exécutons cette requête:

SELECT * FROM `ip2location_db5` WHERE 16843009 > ip_from AND 16843009 < ip_to;

Cela renvoie ces données à titre d'exemple.

FROM: 16843008
TO: 16843263
Country code: AU
Country: Australia
Region: Queensland
City: Brisbane
Latitude: -27.46794
Longitude: 153.02809
2
Crecket

Vous pouvez également utiliser le service "smart-ip":

$.getJSON("http://smart-ip.net/geoip-json?callback=?",
    function (data) {
        alert(data.countryName);
        alert(data.city);
    }
);
2
Roman Pushkin

Si vous recherchez une base de données mise à jour/précise, je vous recommande d'utiliser celle-ci ici car elle indiquait mon emplacement exact, qui n'était pas inclus dans de nombreux autres services lors de mes tests.
(Ma ville était Rasht et mon pays était Iran avec cette adresse IP: 2.187.21.235 lorsque je testais.)

Je recommande d'utiliser la base de données plutôt que les méthodes API, car celle-ci sera traitée beaucoup plus rapidement localement.

0
Mojtaba Rezaeian

J'ai écrit cet article il y a quelques mois et cela pourrait vous être utile. L'article décrit l'utilisation de la base de données open source du pays ip 2 et décrit également une classe php que j'ai écrite pour faire fonctionner cette base de données open source. Voici le lien
http://www.samundra.com.np/find-visitors-country-using-his-ip-address/1018

Si vous avez besoin d’aide à cet égard, envoyez-moi un commentaire sur le site.

J'espère que ça vous aide.

0
Samundra

Il existe 2 approches générales pour effectuer la géolocalisation IP: l’une consiste à télécharger un jeu de données, à l’héberger sur votre infrastructure et à le maintenir à jour. Cela nécessite du temps et des efforts, surtout si vous devez prendre en charge un grand nombre de demandes. Une autre solution consiste à utiliser un service d'API existant qui gère tout le travail pour vous et plus encore.

Il existe de nombreux services de géolocalisation d’API: Maxmind, Ip2location, Ipstack, IpInfo, etc. Récemment, la société pour laquelle je travaille est passée à Ipregistry ( https://ipregistry.co ) et j'ai participé au processus de décision et de mise en œuvre. Voici quelques éléments à prendre en compte lorsque vous recherchez une API de géolocalisation IP:

  • Le service est-il précis? utilisent-ils une seule source d’information?
  • Peuvent-ils vraiment gérer votre charge?
  • Fournissent-ils des temps de réponse cohérents et rapides dans le monde entier (sauf si vos utilisateurs sont spécifiques à un pays)?
  • Quel est leur modèle de tarification?

Voici un exemple pour obtenir des informations de géolocalisation IP (mais également des données de menace et d'agent utilisateur via un seul appel):

$ip = $_SERVER['REMOTE_ADDR'];
$details = json_decode(file_get_contents("https://api.ipregistry.co/{$ip}?key=tryout"));
echo $details->location;

Remarque: je ne suis pas ici pour promouvoir Ipregistry et dire que c'est le meilleur, mais j'ai passé beaucoup de temps à analyser les solutions existantes et leur solution est vraiment prometteuse.

0
BonieE

Ok, les gars, merci pour vos suggestions. Bien que je dispose de plus de 6 000 adresses IP, certains services échouent à mes demandes en raison de certaines limitations; Donc, vous pouvez tous les utiliser en mode de secours;

Si nous avons un fichier source au format suivant:

user_id_1  ip_1
user_id_2  ip_2
user_id_3  ip_1

que vous ne pouvez utiliser cette simple commande d’exemple (PoC) pour Yii:

class GeoIPCommand extends CConsoleCommand
{

public function actionIndex($filename = null)
{
    //http://freegeoip.net/json/{$ip} //10k requests per hour
    //http://ipinfo.io/{$ip}/json //1k per day
    //http://ip-api.com/json/{$ip}?fields=country,city,regionName,status //150 per minute

    echo "start".PHP_EOL;

    $handle      = fopen($filename, "r");
    $destination = './good_locations.txt';
    $bad         = './failed_locations.txt';
    $badIP       = [];
    $goodIP      = [];

    $destHandle = fopen($destination, 'a+');
    $badHandle  = fopen($bad, 'a+');

    if ($handle)
    {
        while (($line = fgets($handle)) !== false)
        {
            $result = preg_match('#(\d+)\s+(\d+\.\d+\.\d+\.\d+)#', $line, $id_ip);
            if(!$result) continue;

            $id = $id_ip[1];
            $ip = $id_ip[2];
            $ok = false;

            if(isset($badIP[$ip])) 
            {
                fputs($badHandle, sprintf('%u %s'. PHP_EOL, $id, $ip));
                continue;
            }

            if(isset($goodIP[$ip]))
            {
                fputs($destHandle, sprintf('"id":"%u","ip":"%s","from":"%s";'. PHP_EOL, $id, $ip, $goodIP[$ip]));
                echo sprintf('"id":"%s","ip":"%s","from":"%s";'. PHP_EOL, $id, $ip, $goodIP[$ip]);
                continue;
            }

            $query = @json_decode(file_get_contents('http://freegeoip.net/json/'.$ip));
            $city = property_exists($query, 'region_name')? $query->region_name : '';
            $city .= property_exists($query, 'city') && $query->city && ($query->city != $city) ? ', ' . $query->city : '';

            if($city)
            {
                fputs($destHandle, sprintf('"id":"%u","ip":"%s","from":"%s";'. PHP_EOL, $id, $ip, $city));
                echo sprintf('"id":"%s","ip":"%s","from":"%s";'. PHP_EOL, $id, $ip, $city);
                $ok = true;
            }

            if(!$ok)
            {
                $query = @json_decode(file_get_contents('http://ip-api.com/json/'. $ip.'?fields=country,city,regionName,status'));
                if($query && $query->status == 'success')
                {
                    $city = property_exists($query, 'regionName')? $query->regionName : '';
                    $city .= property_exists($query, 'city') && $query->city ? ',' . $query->city : '';

                    if($city)
                    {
                        fputs($destHandle, sprintf('"id":"%u","ip":"%s","from":"%s";'. PHP_EOL, $id, $ip, $city));
                        echo sprintf('"id":"%s","ip":"%s","from":"%s";'. PHP_EOL, $id, $ip, $city);
                        $ok = true;
                    }
                }
            }

            if(!$ok)
            {
                $badIP[$ip] = false;
                fputs($badHandle, sprintf('%u %s'. PHP_EOL, $id, $ip));
                echo sprintf('"id":"%s","ip":"%s","from":"%s";'. PHP_EOL, $id, $ip, 'Unknown');
            }

            if($ok)
            {
                $goodIP[$ip] = $city;
            }
        }

        fclose($handle);
        fclose($badHandle);
        fclose($destHandle);
    }else{
        echo 'Can\'t open file' . PHP_EOL; 
        return;
    }

    return;
}

}

C'est une sorte de code merdique, mais ça marche. usage:

./yiic geoip index --filename="./source_id_ip_list.txt"

N'hésitez pas à l'utiliser, à le modifier et à le faire mieux)

0
alexglue