Obtendo a localização de um endereço IP

205

Quero recuperar informações como a cidade, estado e país de um visitante a partir do endereço IP, para que eu possa personalizar minha página da Web de acordo com a localização. Existe uma maneira boa e confiável de fazer isso em PHP? Estou usando JavaScript para scripts do lado do cliente, PHP para scripts do servidor e MySQL para o banco de dados.

Ben Dowling
fonte
Isso é praticamente uma duplicata do stackoverflow.com/questions/348614/… .
5230 Charlie Martin

Respostas:

255

Você pode baixar um banco de dados GeoIP gratuito e pesquisar o endereço IP localmente ou usar um serviço de terceiros e executar uma pesquisa remota. Essa é a opção mais simples, pois não requer configuração, mas introduz latência adicional.

Um serviço de terceiros que você pode usar é o meu, http://ipinfo.io . Eles fornecem nome do host, localização geográfica, proprietário da rede e informações adicionais, por exemplo:

$ 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
}

Aqui está um exemplo do PHP:

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

Você também pode usá-lo no lado do cliente. Aqui está um exemplo simples 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>

Ben Dowling
fonte
1
Convém adicionar um json no final da URL para garantir que você recupere o json em vez da página da web completa. $ detalhes = json_decode (file_get_contents (" ipinfo.io {$ ip} / json"));
Doug
1
@ Manatax Não é, porque seria impossível analisar a resposta do servidor.
Ja͢ck 17/02
3
Não parece um serviço muito confiável. Estou pegando nullo nome da minha cidade. Não é como uma cidade pequena ou algo assim, mas ainda não conseguiu localizá-la. Se não funcionar bem nos EUA, duvido com que frequência também retornará nulo fora dos EUA.
Derek朕會功夫
2
o resultado não é exato. região, cidade postal
Mark Gerryl Mirandilla 26/10
2
AVISO: a partir de janeiro de 2019, algumas pessoas relataram que esse URL do ipinfo é inseguro no vírus, devido ao cavalo de Troia. Os votos foram entre 2015 e 2018
Ricardo
55

Pensei em postar como ninguém parece ter dado informações sobre essa API em particular, mas está retornando exatamente o que estou procurando e você pode fazê-lo retornar em vários formatos json, xml and csv.

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

Isso fornecerá todas as coisas que você poderia desejar:

{
      "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": ""

}
Jamie Hutber
fonte
1
O Jamie FreegeoIp.net não está funcionando. Existe alguma outra maneira?
Adi
Desculpe, não no momento, mas isso é uma pena, pois é o serviço que estou usando em meus sites ao vivo. Vamos esperar que eles voltem algum tempo soo
Jamie Hutber
2
principalmente para baixo e raramente dá qualquer região ou cidade
Rahul aman
2
Serviço do Tony no Azure parece funcionar rápido e confiável: freegeoip2
Gustav
1
Infelizmente, este serviço será desconectado em 1º de julho de 2018, conforme esta mensagem: "Este ponto de extremidade da API foi descontinuado e deixará de funcionar em 1º de julho de 2018. Para obter mais informações, visite: github.com/apilayer/freegeoip#readme \
Julio Bailon
20

Um exemplo puro de Javascript, usando os serviços de https://geolocation-db.com. Eles fornecem uma solução JSON e JSONP-callback.

Não é necessário jQuery!

<!DOCTYPE html>
<html>
<head>
<title>Geo City Locator by geolocation-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://geoilocation-db.com/json/geoip.php?jsonp=callback';
    var h = document.getElementsByTagName('script')[0];
    h.parentNode.insertBefore(script, h);

</script> 
</html>
Kurt Van den Branden
fonte
Existe algum limite relacionado ao uso da https://geoilocation-db.comAPI?
Priyanka Sharma
16

Usando o 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>
Raposo
fonte
9
The geolocation functionality in the Loader hasn't been retired, per se. We stopped documenting it several years ago and have recommended the HTML-based solutions due to their improved accuracy, but the functionality itself has not been removed from the Loader at this time. code.google.com/p/google-ajax-apis/issues/detail?id=586
TheFrost
E a qualidade dessa geolocalização IP do Google APIS? (está ou estou errado?), comparado a outros serviços, como o ipinfo.io ?
Basj
Eu pedi para ~ 30 pessoas em diferentes cidades, e qualidade de geolocalização APIS IP Google é pobre em comparação com ipinfo.io
Basj
1
@Basj Google API funciona como um encanto enquanto ipinfo.io mostra que estou em US enquanto eu estou realmente na Europa central
patryk
15

Você precisa usar um serviço externo ... como http://www.hostip.info/, se você pesquisar no Google por "geo-ip", poderá obter mais resultados.

A API do IP do host é baseada em HTTP, para que você possa usá-la em PHP ou JavaScript, dependendo de suas necessidades.

nulo
fonte
6
Estou usando o hostip.info há um ano e não estou impressionado. Geralmente retorna 9/10 cheques desconhecidos
aron
concordou, está me dizendo que eu moro em Woking ... Para ser justo, acertou um pouco o GB ... Mas estou em Londres.
Jamie Hutber
2
Lembre-se de que qualquer serviço será tão bom quanto as informações / dados públicos disponíveis. Por motivos de privacidade, essas informações podem ser "tão boas". Se o seu país estiver certo e, pelo menos, próximo do estado / província, considero isso uma vitória. Se você estiver usando isso para procurar informações sobre um ataque do DOS, lembre-se de que os IPs podem nem ser válidos (não atribuídos a ninguém ou fora do intervalo de IP público válido).
eselk
No site deles, recebo "Localização: ... na verdade, não temos idéia.". Tudo o que eu precisava saber
Bojan Kogoj
15

Eu escrevi um bot usando uma API do ipapi.co , veja como você pode obter a localização de um endereço IP (por exemplo 1.2.3.4) emphp :

Definir cabeçalho:

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

Obter resposta JSON

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

de obter um campo específico (país, fuso horário etc.)

echo file_get_contents('https://ipapi.co/1.2.3.4/country/', false, $context);
Jaimes
fonte
1
@Eoin o removeu. Parece que o IP do phpfiddle é restrito.
Jaimes
10

Esta questão está protegida, o que eu entendo. No entanto, não vejo uma resposta aqui, o que vejo são muitas pessoas mostrando o que surgiram por terem a mesma pergunta.

Atualmente, existem cinco registros regionais da Internet com diferentes graus de funcionalidade que servem como o primeiro ponto de contato em relação à propriedade de IP. O processo está em andamento, e é por isso que os vários serviços aqui funcionam algumas vezes e outras não.

Quem é (obviamente) é um protocolo TCP antigo, no entanto - a maneira como funcionou originalmente foi pela conexão à porta 43, o que torna problemático obtê-lo roteado através de conexões alugadas, através de firewalls ... etc.

Neste momento - a maioria dos Who Is é feita via HTTP RESTful e ARIN, RIPE e APNIC possuem serviços RESTful que funcionam. O LACNIC retorna um 503 e o AfriNIC aparentemente não possui essa API. (Todos têm serviços online, no entanto.)

Isso fará com que você - o endereço do proprietário registrado do IP, mas - não a localização do seu cliente - você deve obtê-lo e também - você precise solicitá-lo. Além disso, os proxies são a menor das suas preocupações ao validar o IP que você acha que é o originador.

As pessoas não apreciam a noção de que estão sendo rastreadas, então - meus pensamentos são - recebam isso diretamente do seu cliente e com a permissão delas e esperam muito se recusar.

jinzai
fonte
8

Veja a API do hostip.info - ela fornece muitas informações.
Exemplo em 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...

Se você confia no hostip.info, parece ser uma API muito útil.

Isaac Waller
fonte
1
unf. em comparação com outros serviços, o HostIP está fora do ar. www.ip-adress.com, no entanto,
resolve
8

O serviço na resposta de Ben Dowling mudou, agora é mais simples. Para encontrar a localização, basta:

// 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

As coordenadas retornam em uma única sequência como '31, -80 '; portanto, a partir daí, você apenas:

$coordinates = explode(",", $details->loc); // -> '31,-89' becomes'31','-80'
echo $coordinates[0]; // latitude
echo $coordinates[1]; // longitude
Isaac Askew
fonte
4
Você está certo de que o ipinfo.io retornará os detalhes do IP do chamador por padrão. Se você estiver executando um site PHP, esse será o IP do seu servidor, e não o IP do usuário. Essa é a razão pela qual você precisa passar $ _SERVER ['REMOTE_ADDR']. Se você quiser apenas coordenadas, será mais rápido anexar / localizar ao URL para obter apenas esse campo.
Ben Dowling
Ah, é verdade! E eu não sabia sobre o / loc - vou corrigir isso imediatamente no meu próprio site.
Isaac Askew
7

Supondo que você queira fazer isso sozinho e não confiar em outros fornecedores, o IP2Nation fornece um banco de dados MySQL dos mapeamentos que são atualizados à medida que os registros regionais mudam as coisas.

James Cape
fonte
Eu estava usando um serviço externo e, de repente, meu site ficou muito lento. O serviço externo demorou 20 segundos para enviar as informações - o que é obviamente desastroso para os visitantes. Então decidi fazer isso sozinho, e esta é uma solução perfeita. Muito obrigada.
Williamz902
7

Eu executo o serviço no IPLocate.io , no qual você pode conectar-se gratuitamente com uma chamada fácil:

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

O $resobjeto conterá seus campos de localização geográfica, como country,city , etc.

Confira os documentos para obter mais informações.

ttarik
fonte
7

Gosto da GeoLite City gratuita da Maxmind, que funciona para a maioria dos aplicativos e a partir da qual você pode atualizar para uma versão paga, se não for precisa o suficiente. Há uma API PHP incluída, bem como para outros idiomas. E se você estiver executando o Lighttpd como servidor da web, poderá usar um módulo para obter as informações na variável SERVER de cada visitante, se for o que você precisa.

Devo acrescentar que também existe um país Geolite gratuito (que seria mais rápido se você não precisar identificar a cidade da qual o IP é) e o Geolite ASN (se você quiser saber quem é o proprietário do IP) e que finalmente todos esses são para download em seu próprio servidor, são atualizados todos os meses e são bastante rápidos para pesquisar com as APIs fornecidas, pois indicam "milhares de pesquisas por segundo".

lpfavreau
fonte
1
Você pode considerar o IP2Location LITE lite.ip2location.com, que é gratuito. Possui até informações de código postal, o que é muito útil.
Michael C.
6

PHP tem uma extensão para isso.

Do PHP.net:

A extensão GeoIP permite encontrar a localização de um endereço IP. Cidade, estado, país, longitude, latitude e outras informações como todas, como ISP e tipo de conexão, podem ser obtidas com a ajuda do GeoIP.

Por exemplo:

$record = geoip_record_by_name($ip);
echo $record['city'];
Ian Hunter
fonte
3
Este é apenas um módulo php para o banco de dados MaxMind, que é payware. (As versões "lite" gratuitas são altamente imprecisas.) Não é uma coisa ruim, mas é realmente útil apenas para fins comerciais.
Alguém
6

Ipdata.co é uma API de geolocalização de IP rápida e altamente disponível com desempenho confiável.

É extremamente escalável, com 10 terminais em todo o mundo, cada um capaz de lidar com mais de 10.000 solicitações por segundo!

Esta resposta usa uma chave de API 'teste' muito limitada e destinada apenas ao teste de algumas chamadas. Inscreva-se em sua própria chave de API gratuita e receba até 1500 solicitações diárias para desenvolvimento.

Em 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

Aqui está um exemplo do lado do cliente mostrando como você obteria o país, região e cidade;

$.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>

Aviso Legal;

Eu construí o serviço.

Para exemplos em vários idiomas, consulte o Documentos

Veja também esta análise detalhada das melhores APIs de geolocalização de IP.

Jonathan
fonte
5

Caso alguém se depare com esse tópico, aqui está outra solução. No timezoneapi.io, você pode solicitar um endereço IP e obter vários objetos em troca (eu criei o serviço). Foi criado porque eu precisava saber em que fuso horário meus usuários estavam, em que lugar do mundo e a que horas são atualmente.

Em PHP - retorna localização, fuso horário e data / hora:

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

}

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

    }

});
Michael Nilsson
fonte
4

A seguir, uma versão modificada de um snippet que encontrei que usa http://ipinfodb.com/ip_locator.php para obter suas informações. Lembre-se de que você também pode solicitar uma chave de API com eles e usá-la diretamente para obter as informações fornecidas como achar melhor.

Snippet

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

Usar

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" }
SpYk3HH
fonte
4

Se você precisar obter a localização de um endereço IP, poderá usar um serviço geo IP confiável, poderá obter mais detalhes aqui . Ele suporta IPv6.

Como um bônus, permite verificar se o endereço IP é um nó tor, proxy público ou spammer.

Você pode usar javascript ou php como abaixo.

Código 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);
                 });
        });
    });

Código Php:

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

Resultado:

{
"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
}
Vindhyachal Kumar
fonte
3

Eu criei um wrapper para o ipinfo.io . Você pode instalá-lo usando o compositor.

Você pode usá-lo desta maneira:

$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();
Davide Pastore
fonte
2

Você também pode usar o serviço "smart-ip":

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

Fiz vários testes com serviços de endereço IP e aqui estão algumas maneiras de fazer isso sozinho. Primeiro, monte um monte de links para sites úteis que eu uso:

https://db-ip.com/db Possui um serviço de pesquisa de IP gratuito e alguns arquivos CSV gratuitos que você pode baixar. Isso usa uma chave API gratuita anexada ao seu email. Limita a 2000 consultas por dia.

http://ipinfo.io/ Serviço gratuito de pesquisa de ip sem uma função api-key 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
}

No final, você obtém algo parecido com isto:

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/ Um pouco mais antigo, mas este serviço fornece várias informações úteis adicionais, como a moeda do país, código de continente, longitude e muito mais.


http://lite.ip2location.com/database-ip-country-region-city-latitude-longitude Oferece vários arquivos para download com instruções para importá-los para o seu banco de dados. Depois de ter um desses arquivos em seu banco de dados, você pode selecionar os dados facilmente.

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

Use a função php ip2long (); para transformar o endereço IP em um valor numérico. Por exemplo, 1.1.1.1 torna-se 16843009. Isso permite verificar os intervalos de IP fornecidos pelo arquivo do banco de dados.

Portanto, para descobrir onde o 1.1.1.1 pertence a tudo o que fazemos, execute esta consulta:

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

Isso retorna esses dados como um exemplo.

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

Existem duas abordagens amplas para executar a localização geográfica de IP: uma é fazer o download de um conjunto de dados, hospedá-lo em sua infraestrutura e mantê-lo atualizado. Isso requer tempo e esforço, especialmente se você precisar dar suporte a um grande número de solicitações. Outra solução é usar um serviço de API existente que gerencia todo o trabalho para você e muito mais.

Existem muitos serviços de geolocalização da API: Maxmind, Ip2location, Ipstack, IpInfo etc. etc. Recentemente, a empresa na qual trabalho mudou para o Ipregistry ( https://ipregistry.co ) e eu estava envolvido no processo de decisão e implementação. Aqui estão alguns elementos que você deve considerar ao procurar uma API de geolocalização IP:

  • O serviço é preciso? eles estão usando uma única fonte de informação?
  • Eles podem realmente lidar com sua carga?
  • Eles fornecem tempos de resposta rápidos e consistentes em todo o mundo (exceto se seus usuários forem específicos de um país)?
  • Qual é o modelo de preços deles?

Aqui está um exemplo para obter informações de localização geográfica de IP (mas também dados de ameaças e agentes do usuário usando uma chamada):

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

Nota: Não estou aqui para promover o Ipregistry e digo que é o melhor, mas passei muito tempo analisando as soluções existentes e a solução delas é realmente promissora.

BonieE
fonte
-1

Se você estiver procurando por um banco de dados atualizado / preciso, recomendo usá-lo aqui, pois estava mostrando minha localização exata, que não foi incluída em muitos outros serviços durante o teste.
(Minha cidade era Rashte meu país estava Irancom esse endereço IP: 2.187.21.235quando eu estava testando.)

Eu recomendo usar o banco de dados em vez dos métodos da API, porque ele será processado muito mais rapidamente localmente.

Mojtaba Rezaeian
fonte
-1

Ok pessoal, obrigado por suas sugestões; Embora eu tenha mais de 6k de IPs, alguns serviços falharam em minhas solicitações devido a algumas limitações; Então, você pode usá-los todos no modo fallback;

Se tivermos arquivo de origem com o seguinte formato:

user_id_1  ip_1
user_id_2  ip_2
user_id_3  ip_1

do que você poderia usar este comando de exemplo simples (PoC) para 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;
}

}

Este é algum tipo de código de merda, mas funciona. uso:

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

Sinta-se livre para usar, modificá-lo e melhorá-lo)

alexglue
fonte