Conseguir visitantes país desde su IP


220

Quiero que los visitantes ingresen al país a través de su IP ... En este momento estoy usando esto ( http://api.hostip.info/country.php?ip= ......)

Aquí está mi código:

<?php

if (isset($_SERVER['HTTP_CLIENT_IP']))
{
    $real_ip_adress = $_SERVER['HTTP_CLIENT_IP'];
}

if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
{
    $real_ip_adress = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
else
{
    $real_ip_adress = $_SERVER['REMOTE_ADDR'];
}

$cip = $real_ip_adress;
$iptolocation = 'http://api.hostip.info/country.php?ip=' . $cip;
$creatorlocation = file_get_contents($iptolocation);

?>

Bueno, está funcionando correctamente, pero la cuestión es que esto devuelve el código del país como EE. UU. O CA., y no el nombre completo del país, como Estados Unidos o Canadá.

Entonces, ¿hay alguna buena alternativa para que hostip.info ofrezca esto?

Sé que puedo escribir un código que eventualmente convertirá estas dos letras en el nombre completo del país, pero soy demasiado vago para escribir un código que contenga todos los países ...

PD: Por alguna razón, no quiero usar ningún archivo CSV listo o ningún código que pueda obtener esta información para mí, algo como el código IP2country y CSV.


20
No seas perezoso, no hay tantos países, y no es demasiado difícil obtener una tabla de traducción para códigos de letras FIPS 2 a nombres de países.
Chris Henry

Utilice la función de geoip Maxmind. Incluirá el nombre del país en los resultados. maxmind.com/app/php
Tchoupi

Su primera tarea $real_ip_addresssiempre se ignora. De todos modos, recuerde que el X-Forwarded-Forencabezado HTTP se puede falsificar de manera extremadamente fácil, y que hay servidores proxy como www.hidemyass.com
Walter Tross

55
IPLocate.io proporciona una API gratuita: https://www.iplocate.io/api/lookup/8.8.8.8- Descargo de responsabilidad: ejecuto este servicio.
ttarik

Sugiero probar Ipregistry : api.ipregistry.co/… (descargo de responsabilidad: ejecuto el servicio).
Laurent

Respuestas:


495

Prueba esta sencilla función PHP.

<?php

function ip_info($ip = NULL, $purpose = "location", $deep_detect = TRUE) {
    $output = NULL;
    if (filter_var($ip, FILTER_VALIDATE_IP) === FALSE) {
        $ip = $_SERVER["REMOTE_ADDR"];
        if ($deep_detect) {
            if (filter_var(@$_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP))
                $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
            if (filter_var(@$_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP))
                $ip = $_SERVER['HTTP_CLIENT_IP'];
        }
    }
    $purpose    = str_replace(array("name", "\n", "\t", " ", "-", "_"), NULL, strtolower(trim($purpose)));
    $support    = array("country", "countrycode", "state", "region", "city", "location", "address");
    $continents = array(
        "AF" => "Africa",
        "AN" => "Antarctica",
        "AS" => "Asia",
        "EU" => "Europe",
        "OC" => "Australia (Oceania)",
        "NA" => "North America",
        "SA" => "South America"
    );
    if (filter_var($ip, FILTER_VALIDATE_IP) && in_array($purpose, $support)) {
        $ipdat = @json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip=" . $ip));
        if (@strlen(trim($ipdat->geoplugin_countryCode)) == 2) {
            switch ($purpose) {
                case "location":
                    $output = array(
                        "city"           => @$ipdat->geoplugin_city,
                        "state"          => @$ipdat->geoplugin_regionName,
                        "country"        => @$ipdat->geoplugin_countryName,
                        "country_code"   => @$ipdat->geoplugin_countryCode,
                        "continent"      => @$continents[strtoupper($ipdat->geoplugin_continentCode)],
                        "continent_code" => @$ipdat->geoplugin_continentCode
                    );
                    break;
                case "address":
                    $address = array($ipdat->geoplugin_countryName);
                    if (@strlen($ipdat->geoplugin_regionName) >= 1)
                        $address[] = $ipdat->geoplugin_regionName;
                    if (@strlen($ipdat->geoplugin_city) >= 1)
                        $address[] = $ipdat->geoplugin_city;
                    $output = implode(", ", array_reverse($address));
                    break;
                case "city":
                    $output = @$ipdat->geoplugin_city;
                    break;
                case "state":
                    $output = @$ipdat->geoplugin_regionName;
                    break;
                case "region":
                    $output = @$ipdat->geoplugin_regionName;
                    break;
                case "country":
                    $output = @$ipdat->geoplugin_countryName;
                    break;
                case "countrycode":
                    $output = @$ipdat->geoplugin_countryCode;
                    break;
            }
        }
    }
    return $output;
}

?>

Cómo utilizar:

Ejemplo 1: Obtener detalles de la dirección IP del visitante

<?php

echo ip_info("Visitor", "Country"); // India
echo ip_info("Visitor", "Country Code"); // IN
echo ip_info("Visitor", "State"); // Andhra Pradesh
echo ip_info("Visitor", "City"); // Proddatur
echo ip_info("Visitor", "Address"); // Proddatur, Andhra Pradesh, India

print_r(ip_info("Visitor", "Location")); // Array ( [city] => Proddatur [state] => Andhra Pradesh [country] => India [country_code] => IN [continent] => Asia [continent_code] => AS )

?>

Ejemplo 2: Obtenga detalles de cualquier dirección IP. [Soporte IPV4 e IPV6]

<?php

echo ip_info("173.252.110.27", "Country"); // United States
echo ip_info("173.252.110.27", "Country Code"); // US
echo ip_info("173.252.110.27", "State"); // California
echo ip_info("173.252.110.27", "City"); // Menlo Park
echo ip_info("173.252.110.27", "Address"); // Menlo Park, California, United States

print_r(ip_info("173.252.110.27", "Location")); // Array ( [city] => Menlo Park [state] => California [country] => United States [country_code] => US [continent] => North America [continent_code] => NA )

?>

1
¿Por qué me desconozco todo el tiempo con cada ip? , utilizó el mismo código.
echo_Me

1
Obtendrá "Desconocido" probablemente porque su servidor no lo permite file_get_contents(). Simplemente revise su archivo error_log. Solución alternativa: vea mi respuesta.
Kai Noack

3
también puede ser porque lo verifica localmente (192.168.1.1 / 127.0.0.1 / 10.0.0.1)
Hontoni,

1
Recuerde guardar en caché los resultados durante un período definido. Además, como nota, nunca debe confiar en otro sitio web para obtener datos, el sitio web podría fallar, el servicio podría detenerse, etc. Y si obtiene un mayor número de visitantes en su sitio web, este servicio podría prohibirlo.
machineaddict

1
Siga: este es un problema al probar un sitio en localhost. ¿Alguna forma de arreglarlo con fines de prueba? Utiliza el IP localhost 127.0.0.1 estándar
Nick

54

Puede usar una API simple desde http://www.geoplugin.net/

$xml = simplexml_load_file("http://www.geoplugin.net/xml.gp?ip=".getRealIpAddr());
echo $xml->geoplugin_countryName ;


echo "<pre>";
foreach ($xml as $key => $value)
{
    echo $key , "= " , $value ,  " \n" ;
}
echo "</pre>";

Función utilizada

function getRealIpAddr()
{
    if (!empty($_SERVER['HTTP_CLIENT_IP']))   //check ip from share internet
    {
      $ip=$_SERVER['HTTP_CLIENT_IP'];
    }
    elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))   //to check ip is pass from proxy
    {
      $ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
    }
    else
    {
      $ip=$_SERVER['REMOTE_ADDR'];
    }
    return $ip;
}

Salida

United States
geoplugin_city= San Antonio
geoplugin_region= TX
geoplugin_areaCode= 210
geoplugin_dmaCode= 641
geoplugin_countryCode= US
geoplugin_countryName= United States
geoplugin_continentCode= NA
geoplugin_latitude= 29.488899230957
geoplugin_longitude= -98.398696899414
geoplugin_regionCode= TX
geoplugin_regionName= Texas
geoplugin_currencyCode= USD
geoplugin_currencySymbol= $
geoplugin_currencyConverter= 1

Te hace tener tantas opciones con las que puedes jugar

Gracias

:)


1
Eso es realmente genial. Pero durante la prueba aquí no hay valores en los siguientes campos "geoplugin_city, geoplugin_region, geoplugin_regionCode, geoplugin_regionName" .. ¿Cuál es la razón? ¿Hay alguna solución? Gracias de antemano
WebDevRon

31

Intenté la respuesta de Chandra pero la configuración de mi servidor no permite file_get_contents ()

PHP Warning: file_get_contents() URL file-access is disabled in the server configuration

Modifiqué el código de Chandra para que también funcione para servidores como ese usando cURL:

function ip_visitor_country()
{

    $client  = @$_SERVER['HTTP_CLIENT_IP'];
    $forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
    $remote  = $_SERVER['REMOTE_ADDR'];
    $country  = "Unknown";

    if(filter_var($client, FILTER_VALIDATE_IP))
    {
        $ip = $client;
    }
    elseif(filter_var($forward, FILTER_VALIDATE_IP))
    {
        $ip = $forward;
    }
    else
    {
        $ip = $remote;
    }
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "http://www.geoplugin.net/json.gp?ip=".$ip);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    $ip_data_in = curl_exec($ch); // string
    curl_close($ch);

    $ip_data = json_decode($ip_data_in,true);
    $ip_data = str_replace('&quot;', '"', $ip_data); // for PHP 5.2 see stackoverflow.com/questions/3110487/

    if($ip_data && $ip_data['geoplugin_countryName'] != null) {
        $country = $ip_data['geoplugin_countryName'];
    }

    return 'IP: '.$ip.' # Country: '.$country;
}

echo ip_visitor_country(); // output Coutry name

?>

Espero que ayude ;-)


2
De acuerdo con los documentos en su sitio: "Si geoplugin.net estaba respondiendo perfectamente, luego se detuvo, entonces ha superado el límite de búsqueda gratuita de 120 solicitudes por minuto".
Rick Hellewell

Funcionó muy bien. ¡Gracias!
Najeeb


11

Use MaxMind GeoIP (o GeoIPLite si no está listo para pagar).

$gi = geoip_open('GeoIP.dat', GEOIP_MEMORY_CACHE);
$country = geoip_country_code_by_addr($gi, $_SERVER['REMOTE_ADDR']);
geoip_close($gi);

@Joyce: Traté de usar Maxmind API y DB, pero no sé por qué no funciona para mí, en realidad funciona en general, pero por ejemplo cuando ejecuto este $ _SERVER ['REMOTE_ADDR']; me muestra this ip: 10.48.44.43, pero cuando lo uso en geoip_country_code_by_addr ($ gi, $ ip), no devuelve nada, ¿alguna idea?
mOna

Es una dirección IP reservada (dirección IP interna de su red local). Intente ejecutar el código en un servidor remoto.
Joyce Babu


10

Echa un vistazo a php-ip-2-country desde code.google. La base de datos que proporcionan se actualiza a diario, por lo que no es necesario conectarse a un servidor externo para verificar si aloja su propio servidor SQL. Entonces, usando el código, solo tendría que escribir:

<?php
$ip = $_SERVER['REMOTE_ADDR'];

if(!empty($ip)){
        require('./phpip2country.class.php');

        /**
         * Newest data (SQL) avaliable on project website
         * @link http://code.google.com/p/php-ip-2-country/
         */
        $dbConfigArray = array(
                'host' => 'localhost', //example host name
                'port' => 3306, //3306 -default mysql port number
                'dbName' => 'ip_to_country', //example db name
                'dbUserName' => 'ip_to_country', //example user name
                'dbUserPassword' => 'QrDB9Y8CKMdLDH8Q', //example user password
                'tableName' => 'ip_to_country', //example table name
        );

        $phpIp2Country = new phpIp2Country($ip,$dbConfigArray);
        $country = $phpIp2Country->getInfo(IP_COUNTRY_NAME);
        echo $country;
?>

Código de ejemplo (del recurso)

<?
require('phpip2country.class.php');

$dbConfigArray = array(
        'host' => 'localhost', //example host name
        'port' => 3306, //3306 -default mysql port number
        'dbName' => 'ip_to_country', //example db name
        'dbUserName' => 'ip_to_country', //example user name
        'dbUserPassword' => 'QrDB9Y8CKMdLDH8Q', //example user password
        'tableName' => 'ip_to_country', //example table name
);

$phpIp2Country = new phpIp2Country('213.180.138.148',$dbConfigArray);

print_r($phpIp2Country->getInfo(IP_INFO));
?>

Salida

Array
(
    [IP_FROM] => 3585376256
    [IP_TO] => 3585384447
    [REGISTRY] => RIPE
    [ASSIGNED] => 948758400
    [CTRY] => PL
    [CNTRY] => POL
    [COUNTRY] => POLAND
    [IP_STR] => 213.180.138.148
    [IP_VALUE] => 3585378964
    [IP_FROM_STR] => 127.255.255.255
    [IP_TO_STR] => 127.255.255.255
)

44
debemos proporcionar información de la base de datos para trabajar? no parece bueno
echo_Me

10

Podemos usar geobytes.com para obtener la ubicación usando la dirección IP del usuario

$user_ip = getIP();
$meta_tags = get_meta_tags('http://www.geobytes.com/IPLocator.htm?GetLocation&template=php3.txt&IPAddress=' . $user_ip);
echo '<pre>';
print_r($meta_tags);

devolverá datos como este

Array(
    [known] => true
    [locationcode] => USCALANG
    [fips104] => US
    [iso2] => US
    [iso3] => USA
    [ison] => 840
    [internet] => US
    [countryid] => 254
    [country] => United States
    [regionid] => 126
    [region] => California
    [regioncode] => CA
    [adm1code] =>     
    [cityid] => 7275
    [city] => Los Angeles
    [latitude] => 34.0452
    [longitude] => -118.2840
    [timezone] => -08:00
    [certainty] => 53
    [mapbytesremaining] => Free
)

Función para obtener la IP del usuario

function getIP(){
if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])){
    $pattern = "/^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/";
    if(preg_match($pattern, $_SERVER["HTTP_X_FORWARDED_FOR"])){
            $userIP = $_SERVER["HTTP_X_FORWARDED_FOR"];
    }else{
            $userIP = $_SERVER["REMOTE_ADDR"];
    }
}
else{
  $userIP = $_SERVER["REMOTE_ADDR"];
}
return $userIP;
}

Probé su código, me lo devuelve: Array ([conocido] => false)
mOna

cuando intento esto: $ ip = $ _SERVER ["REMOTE_ADDR"]; echo $ ip; lo devuelve: 10.48.44.43, ¿sabes cuál es el problema? Solía alspo geoıp MaxMind, y cuando utilicé geoip_country_name_by_addr ($ gi, $ ip) againit me devolvió nada ...
Mona

@ mOna, devuelve tu dirección IP. para más detalles por favor, comparta su código.
Ram Sharma

Encontré que el problema está relacionado con mi ip ya que es para una red privada. luego utilicé mi ip real en ifconfig y la usé en mi programa. entonces funcionó :) Ahora, mi pregunta es cómo obtener una IP real en el caso de aquellos usuarios similares a mí. (si usan IP local) ... escribí mi código aquí: stackoverflow.com/questions/25958564/…
mOna

9

Pruebe este código simple de una línea. Obtendrá el país y la ciudad de los visitantes desde su dirección remota IP.

$tags = get_meta_tags('http://www.geobytes.com/IpLocator.htm?GetLocation&template=php3.txt&IpAddress=' . $_SERVER['REMOTE_ADDR']);
echo $tags['country'];
echo $tags['city'];

9

Puede utilizar un servicio web de http://ip-api.com
en su código php, haga lo siguiente:

<?php
$ip = $_REQUEST['REMOTE_ADDR']; // the IP address to query
$query = @unserialize(file_get_contents('http://ip-api.com/php/'.$ip));
if($query && $query['status'] == 'success') {
  echo 'Hello visitor from '.$query['country'].', '.$query['city'].'!';
} else {
  echo 'Unable to get location';
}
?>

la consulta tiene muchas otras informaciones:

array (
  'status'      => 'success',
  'country'     => 'COUNTRY',
  'countryCode' => 'COUNTRY CODE',
  'region'      => 'REGION CODE',
  'regionName'  => 'REGION NAME',
  'city'        => 'CITY',
  'zip'         => ZIP CODE,
  'lat'         => LATITUDE,
  'lon'         => LONGITUDE,
  'timezone'    => 'TIME ZONE',
  'isp'         => 'ISP NAME',
  'org'         => 'ORGANIZATION NAME',
  'as'          => 'AS NUMBER / NAME',
  'query'       => 'IP ADDRESS USED FOR QUERY',
)

¡Usé ip-api.com porque también proporcionan el nombre del ISP!
Richard Tinkler

1
Usé porque también suministran la zona horaria
Roy Shoa

8

Existe una versión de archivo plano bien mantenida de la base de datos ip-> country mantenida por la comunidad Perl en CPAN

El acceso a esos archivos no requiere un servidor de datos, y los datos en sí son aproximadamente 515k

Higemaru ha escrito un contenedor PHP para hablar con esos datos: php-ip-country-fast


6

Muchas formas diferentes de hacerlo ...

Solución # 1:

Un servicio de terceros que podría utilizar es http://ipinfodb.com . Proporcionan nombre de host, geolocalización e información adicional.

Regístrese para obtener una clave API aquí: http://ipinfodb.com/register.php . Esto le permitirá recuperar resultados de su servidor, sin esto no funcionará.

Copie y pegue el siguiente código PHP:

$ipaddress = $_SERVER['REMOTE_ADDR'];
$api_key = 'YOUR_API_KEY_HERE';

$data = file_get_contents("http://api.ipinfodb.com/v3/ip-city/?key=$api_key&ip=$ipaddress&format=json");
$data = json_decode($data);
$country = $data['Country'];

Abajo:

Citando desde su sitio web:

Nuestra API gratuita está utilizando la versión IP2Location Lite que proporciona una precisión menor.

Solución # 2:

Esta función devolverá el nombre del país utilizando el servicio http://www.netip.de/ .

$ipaddress = $_SERVER['REMOTE_ADDR'];
function geoCheckIP($ip)
{
    $response=@file_get_contents('http://www.netip.de/search?query='.$ip);

    $patterns=array();
    $patterns["country"] = '#Country: (.*?)&nbsp;#i';

    $ipInfo=array();

    foreach ($patterns as $key => $pattern)
    {
        $ipInfo[$key] = preg_match($pattern,$response,$value) && !empty($value[1]) ? $value[1] : 'not found';
    }

        return $ipInfo;
}

print_r(geoCheckIP($ipaddress));

Salida:

Array ( [country] => DE - Germany )  // Full Country Name

3
Citando desde su sitio web: "Usted está limitado a 1,000 solicitudes API por día. Si necesita hacer más solicitudes o necesita soporte SSL, consulte nuestros planes pagos".
Walter Tross

Lo usé en mi sitio web personal, por eso lo publiqué. Gracias por la información ... no me di cuenta. Puse mucho más esfuerzo en la publicación, así que por favor vea la publicación actualizada :)
imbondbaby

@imbondbaby: Hola, probé su código, pero para mí devuelve esto: Array ([country] => -), no entiendo el problema desde que intento imprimir esto: $ ipaddress = $ _SERVER ['REMOTE_ADDR' ]; me muestra esta ip: 10.48.44.43, ¡no puedo entender por qué esta ip no funciona! Me refiero a donde sea que inserte este número, ¡no devuelve ningún país! ¿Por favor me ayudas?
mOna

5

¡Mi servicio ipdata.co proporciona el nombre del país en 5 idiomas! Además de la organización, la moneda, la zona horaria, el código de llamada, la bandera, los datos del operador de telefonía móvil, los datos de proxy y los datos de estado del nodo de salida Tor de cualquier dirección IPv4 o IPv6.

Esta respuesta utiliza una clave API 'prueba' que es muy limitada y solo está destinada a probar algunas llamadas. Regístrese para obtener su propia clave API gratuita y obtenga hasta 1500 solicitudes diarias de desarrollo.

¡También es extremadamente escalable con 10 regiones en todo el mundo, cada una capaz de manejar> 10,000 solicitudes por segundo!

Las opciones incluyen; Inglés (en), alemán (de), japonés (ja), francés (fr) y chino simplificado (za-CH)

$ip = '74.125.230.195';
$details = json_decode(file_get_contents("https://api.ipdata.co/{$ip}?api-key=test"));
echo $details->country_name;
//United States
echo $details->city;
//Mountain View
$details = json_decode(file_get_contents("https://api.ipdata.co/{$ip}?api-key=test/zh-CN"));
echo $details->country_name;
//美国

1
Dios te bendiga, hombre! ¡Obtuve más de lo que pedí! Pregunta rápida: ¿puedo usarlo para productos? Quiero decir, no lo vas a dejar en el corto plazo, ¿verdad?
Sayed

1
Para nada :) De hecho, estoy agregando más regiones y más esmalte. Me alegra que hayas encontrado esto útil :)
Jonathan

¡Muy útil, especialmente con los parámetros adicionales, resolvió más de un problema para mí!
Sayed

3
Gracias por los comentarios positivos! Construí alrededor de los casos de uso más comunes para una herramienta de este tipo, el objetivo era eliminar la necesidad de realizar cualquier procesamiento adicional después de la geolocalización, feliz de ver que esto valga la pena para los usuarios
Jonathan

4

No estoy seguro si este es un servicio nuevo, pero ahora (2016) la forma más fácil en php es usar el servicio web php de geoplugin: http://www.geoplugin.net/php.gp :

Uso básico:

// GET IP ADDRESS
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
} else if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else if (!empty($_SERVER['REMOTE_ADDR'])) {
    $ip = $_SERVER['REMOTE_ADDR'];
} else {
    $ip = false;
}

// CALL THE WEBSERVICE
$ip_info = unserialize(file_get_contents('http://www.geoplugin.net/php.gp?ip='.$ip));

También proporcionan una clase preparada: http://www.geoplugin.com/_media/webservices/geoplugin.class.php.tgz?id=webservices%3Aphp&cache=cache


Usaste un elseafter elseque causa un error. ¿Qué trataste de prevenir? ¿REMOTE_ADDR debería estar disponible todo el tiempo?
AlexioVay

@Vaia - Tal vez debería ser, pero nunca se sabe.
billynoah

¿Hay algún caso en el que no esté disponible?
AlexioVay

2
@Vaia: de los documentos de PHP en adelante $_SERVER: "No hay garantía de que cada servidor web proporcione ninguno de estos; los servidores pueden omitir algunos o proporcionar otros que no figuran aquí".
billynoah

1
Tenga en cuenta que hay un límite para las solicitudes; de su sitio: "Si geoplugin.net estaba respondiendo perfectamente, luego se detuvo, entonces ha superado el límite de búsqueda gratuita de 120 solicitudes por minuto".
Rick Hellewell

2

Estoy usando ipinfodb.comapi y obtengo exactamente lo que estás buscando.

Es completamente gratis, solo necesita registrarse con ellos para obtener su clave de API. Puede incluir su clase de PHP descargándola de su sitio web o puede usar el formato de URL para recuperar información.

Esto es lo que estoy haciendo:

Incluí su clase php en mi script y usé el siguiente código:

$ipLite = new ip2location_lite;
$ipLite->setKey('your_api_key');
if(!$_COOKIE["visitorCity"]){ //I am using cookie to store information
  $visitorCity = $ipLite->getCity($_SERVER['REMOTE_ADDR']);
  if ($visitorCity['statusCode'] == 'OK') {
    $data = base64_encode(serialize($visitorCity));
    setcookie("visitorCity", $data, time()+3600*24*7); //set cookie for 1 week
  }
}
$visitorCity = unserialize(base64_decode($_COOKIE["visitorCity"]));
echo $visitorCity['countryName'].' Region'.$visitorCity['regionName'];

Eso es.


2

puede usar http://ipinfo.io/ para obtener detalles de la dirección IP. Es fácil de usar.

<?php
    function ip_details($ip)
    {
    $json = file_get_contents("http://ipinfo.io/{$ip}");
    $details = json_decode($json);
    return $details;
    }

    $details = ip_details(YoUR IP ADDRESS); 

    echo $details->city;
    echo "<br>".$details->country; 
    echo "<br>".$details->org; 
    echo "<br>".$details->hostname; /

    ?>

2

Reemplazar 127.0.0.1con visitantes IpAddress.

$country = geoip_country_name_by_name('127.0.0.1');

Las instrucciones de instalación están aquí , y lea esto para saber cómo obtener Ciudad, Estado, País, Longitud, Latitud, etc.


Proporcione más código real que solo enlaces duros.
Bram Vanroy

Noticias posteriores del enlace: "A partir del 2 de enero de 2019, Maxmind suspendió las bases de datos originales de GeoLite que hemos estado utilizando en todos estos ejemplos. Puede leer el anuncio completo aquí: support.maxmind.com/geolite-legacy-discontinuation-notice "
Rick Hellewell


2

Tengo una respuesta corta que he usado en un proyecto. En mi respuesta, considero que tiene una dirección IP de visitante.

$ip = "202.142.178.220";
$ipdat = @json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip=" . $ip));
//get ISO2 country code
if(property_exists($ipdat, 'geoplugin_countryCode')) {
    echo $ipdat->geoplugin_countryCode;
}
//get country full name
if(property_exists($ipdat, 'geoplugin_countryName')) {
    echo $ipdat->geoplugin_countryName;
}

1

Sé que esto es antiguo, pero probé algunas otras soluciones aquí y parecen estar desactualizadas o simplemente devuelven nulo. Así es como lo hice.

Uso http://www.geoplugin.net/json.gp?ip=que no requiere ningún tipo de registro o pago por el servicio.

function get_client_ip_server() {
  $ipaddress = '';
if (isset($_SERVER['HTTP_CLIENT_IP']))
  $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
else if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
  $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
else if(isset($_SERVER['HTTP_X_FORWARDED']))
  $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
else if(isset($_SERVER['HTTP_FORWARDED_FOR']))
  $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
else if(isset($_SERVER['HTTP_FORWARDED']))
  $ipaddress = $_SERVER['HTTP_FORWARDED'];
else if(isset($_SERVER['REMOTE_ADDR']))
  $ipaddress = $_SERVER['REMOTE_ADDR'];
else
  $ipaddress = 'UNKNOWN';

  return $ipaddress;
}

$ipaddress = get_client_ip_server();

function getCountry($ip){
    $curlSession = curl_init();
    curl_setopt($curlSession, CURLOPT_URL, 'http://www.geoplugin.net/json.gp?ip='.$ip);
    curl_setopt($curlSession, CURLOPT_BINARYTRANSFER, true);
    curl_setopt($curlSession, CURLOPT_RETURNTRANSFER, true);

    $jsonData = json_decode(curl_exec($curlSession));
    curl_close($curlSession);

    return $jsonData->geoplugin_countryCode;
}

echo "County: " .getCountry($ipaddress);

Y si desea información adicional al respecto, este es un retorno completo de Json:

{
  "geoplugin_request":"IP_ADDRESS",
  "geoplugin_status":200,
  "geoplugin_delay":"2ms",
  "geoplugin_credit":"Some of the returned data includes GeoLite data created by MaxMind, available from <a href='http:\/\/www.maxmind.com'>http:\/\/www.maxmind.com<\/a>.",
  "geoplugin_city":"Current City",
  "geoplugin_region":"Region",
  "geoplugin_regionCode":"Region Code",
  "geoplugin_regionName":"Region Name",
  "geoplugin_areaCode":"",
  "geoplugin_dmaCode":"650",
  "geoplugin_countryCode":"US",
  "geoplugin_countryName":"United States",
  "geoplugin_inEU":0,
  "geoplugin_euVATrate":false,
  "geoplugin_continentCode":"NA",
  "geoplugin_continentName":"North America",
  "geoplugin_latitude":"37.5563",
  "geoplugin_longitude":"-99.9413",
  "geoplugin_locationAccuracyRadius":"5",
  "geoplugin_timezone":"America\/Chicago",
  "geoplugin_currencyCode":"USD",
  "geoplugin_currencySymbol":"$",
  "geoplugin_currencySymbol_UTF8":"$",
  "geoplugin_currencyConverter":1
}

1

He escrito una clase basada en la respuesta "Chandra Nakka". Con suerte, puede ayudar a las personas a guardar la información del geoplugin en una sesión para que la carga sea mucho más rápida al recuperar la información. También guarda los valores en una matriz privada, por lo que recuperarlos en el mismo código es lo más rápido posible.

class Geo {
private $_ip = null;
private $_useSession = true;
private $_sessionNameData = 'GEO_SESSION_DATA';
private $_hasError = false;
private $_geoData = [];

const PURPOSE_SUPPORT = [
    "all", "*", "location",
    "request",
    "latitude", 
    "longitude",
    "accuracy",
    "timezonde",
    "currencycode",
    "currencysymbol",
    "currencysymbolutf8",
    "country", 
    "countrycode", 
    "state", "region", 
    "city", 
    "address",
    "continent", 
    "continentcode"
];
const CONTINENTS = [
    "AF" => "Africa",
    "AN" => "Antarctica",
    "AS" => "Asia",
    "EU" => "Europe",
    "OC" => "Australia (Oceania)",
    "NA" => "North America",
    "SA" => "South America"
];

function __construct($ip = null, $deepDetect = true, $useSession = true)
{
    // define the session useage within this class
    $this->_useSession = $useSession;
    $this->_startSession();

    // define a ip as far as possible
    $this->_ip = $this->_defineIP($ip, $deepDetect);

    // check if the ip was set
    if (!$this->_ip) {
        $this->_hasError = true;
        return $this;
    }

    // define the geoData
    $this->_geoData = $this->_fetchGeoData();

    return $this;
}

function get($purpose)
{
    // making sure its lowercase
    $purpose = strtolower($purpose);

    // makeing sure there are no error and the geodata is not empty
    if ($this->_hasError || !count($this->_geoData) && !in_array($purpose, self::PURPOSE_SUPPORT)) {
        return 'error';
    }

    if (in_array($purpose, ['*', 'all', 'location']))  {
        return $this->_geoData;
    }

    if ($purpose === 'state') $purpose = 'region';

    return (isset($this->_geoData[$purpose]) ? $this->_geoData[$purpose] : 'missing: '.$purpose);
}

private function _fetchGeoData()
{
    // check if geo data was set before
    if (count($this->_geoData)) {
        return $this->_geoData;
    }

    // check possible session
    if ($this->_useSession && ($sessionData = $this->_getSession($this->_sessionNameData))) {
        return $sessionData;
    }

    // making sure we have a valid ip
    if (!$this->_ip || $this->_ip === '127.0.0.1') {
        return [];
    }

    // fetch the information from geoplusing
    $ipdata = @json_decode($this->curl("http://www.geoplugin.net/json.gp?ip=" . $this->_ip));

    // check if the data was fetched
    if (!@strlen(trim($ipdata->geoplugin_countryCode)) === 2) {
        return [];
    }

    // make a address array
    $address = [$ipdata->geoplugin_countryName];
    if (@strlen($ipdata->geoplugin_regionName) >= 1)
        $address[] = $ipdata->geoplugin_regionName;
    if (@strlen($ipdata->geoplugin_city) >= 1)
        $address[] = $ipdata->geoplugin_city;

    // makeing sure the continentCode is upper case
    $continentCode = strtoupper(@$ipdata->geoplugin_continentCode);

    $geoData = [
        'request' => @$ipdata->geoplugin_request,
        'latitude' => @$ipdata->geoplugin_latitude,
        'longitude' => @$ipdata->geoplugin_longitude,
        'accuracy' => @$ipdata->geoplugin_locationAccuracyRadius,
        'timezonde' => @$ipdata->geoplugin_timezone,
        'currencycode' => @$ipdata->geoplugin_currencyCode,
        'currencysymbol' => @$ipdata->geoplugin_currencySymbol,
        'currencysymbolutf8' => @$ipdata->geoplugin_currencySymbol_UTF8,
        'city' => @$ipdata->geoplugin_city,
        'region' => @$ipdata->geoplugin_regionName,
        'country' => @$ipdata->geoplugin_countryName,
        'countrycode' => @$ipdata->geoplugin_countryCode,
        'continent' => self::CONTINENTS[$continentCode],
        'continentcode' => $continentCode,
        'address' => implode(", ", array_reverse($address))
    ];

    if ($this->_useSession) {
        $this->_setSession($this->_sessionNameData, $geoData);
    }

    return $geoData;
}

private function _startSession()
{
    // only start a new session when the status is 'none' and the class
    // requires a session
    if ($this->_useSession && session_status() === PHP_SESSION_NONE) {
        session_start();
    }
}

private function _defineIP($ip, $deepDetect)
{
    // check if the ip was set before
    if ($this->_ip) {
        return $this->_ip;
    }

    // check if the ip given is valid
    if (filter_var($ip, FILTER_VALIDATE_IP)) {
        return $ip;
    }

    // try to get the ip from the REMOTE_ADDR
    $ip = filter_input(INPUT_SERVER, 'REMOTE_ADDR', FILTER_VALIDATE_IP);

    // check if we need to end the search for a IP if the REMOTE_ADDR did not
    // return a valid and the deepDetect is false
    if (!$deepDetect) {
        return $ip;
    }

    // try to get the ip from HTTP_X_FORWARDED_FOR
    if (($ip = filter_input(INPUT_SERVER, 'HTTP_X_FORWARDED_FOR', FILTER_VALIDATE_IP))) {
        return $ip;
    }

    // try to get the ip from the HTTP_CLIENT_IP
    if (($ip = filter_input(INPUT_SERVER, 'HTTP_CLIENT_IP', FILTER_VALIDATE_IP))) {
        return $ip;
    }

    return $ip;
}

private function _hasSession($key, $filter = FILTER_DEFAULT) 
{
    return (isset($_SESSION[$key]) ? (bool)filter_var($_SESSION[$key], $filter) : false);
}

private function _getSession($key, $filter = FILTER_DEFAULT)
{
    if ($this->_hasSession($key, $filter)) {
        $value = filter_var($_SESSION[$key], $filter);

        if (@json_decode($value)) {
            return json_decode($value, true);
        }

        return filter_var($_SESSION[$key], $filter);
    } else {
        return false;
    }
}

private function _setSession($key, $value) 
{
    if (is_array($value)) {
        $value = json_encode($value);
    }

    $_SESSION[$key] = $value;
}

function emptySession($key) {
    if (!$this->_hasSession($key)) {
        return;
    }

    $_SESSION[$key] = null;
    unset($_SESSION[$key]);

}

function curl($url) 
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($ch);
    curl_close($ch);
    return $output;
}
}

Respondiendo la pregunta 'op' con esta clase puedes llamar

$country = (new \Geo())->get('country'); // United Kingdom

Y las otras propiedades disponibles son:

$geo = new \Geo('185.35.50.4');
var_dump($geo->get('*')); // allias all / location
var_dump($geo->get('country'));
var_dump($geo->get('countrycode'));
var_dump($geo->get('state')); // allias region
var_dump($geo->get('city')); 
var_dump($geo->get('address')); 
var_dump($geo->get('continent')); 
var_dump($geo->get('continentcode'));   
var_dump($geo->get('request'));
var_dump($geo->get('latitude'));
var_dump($geo->get('longitude'));
var_dump($geo->get('accuracy'));
var_dump($geo->get('timezonde'));
var_dump($geo->get('currencyCode'));
var_dump($geo->get('currencySymbol'));
var_dump($geo->get('currencySymbolUTF8'));

Volviendo

array(15) {
  ["request"]=>
  string(11) "185.35.50.4"
  ["latitude"]=>
  string(7) "51.4439"
  ["longitude"]=>
  string(7) "-0.1854"
  ["accuracy"]=>
  string(2) "50"
  ["timezonde"]=>
  string(13) "Europe/London"
  ["currencycode"]=>
  string(3) "GBP"
  ["currencysymbol"]=>
  string(2) "£"
  ["currencysymbolutf8"]=>
  string(2) "£"
  ["city"]=>
  string(10) "Wandsworth"
  ["region"]=>
  string(10) "Wandsworth"
  ["country"]=>
  string(14) "United Kingdom"
  ["countrycode"]=>
  string(2) "GB"
  ["continent"]=>
  string(6) "Europe"
  ["continentcode"]=>
  string(2) "EU"
  ["address"]=>
  string(38) "Wandsworth, Wandsworth, United Kingdom"
}
string(14) "United Kingdom"
string(2) "GB"
string(10) "Wandsworth"
string(10) "Wandsworth"
string(38) "Wandsworth, Wandsworth, United Kingdom"
string(6) "Europe"
string(2) "EU"
string(11) "185.35.50.4"
string(7) "51.4439"
string(7) "-0.1854"
string(2) "50"
string(13) "Europe/London"
string(3) "GBP"
string(2) "£"
string(2) "£"

0

La API del país del usuario tiene exactamente lo que necesita. Aquí hay un código de muestra usando file_get_contents () como lo hace originalmente:

$result = json_decode(file_get_contents('http://usercountry.com/v1.0/json/'.$cip), true);
$result['country']['name']; // this contains what you need

1
Esta API permite 100 llamadas de API (gratis) por día.
reformado

0

Puede obtener visitantes país y ciudad utilizando ipstack geo API. Necesita obtener su propia API de ipstack y luego usar el siguiente código:

<?php
 $ip = $_SERVER['REMOTE_ADDR']; 
 $api_key = "YOUR_API_KEY";
 $freegeoipjson = file_get_contents("http://api.ipstack.com/".$ip."?access_key=".$api_key."");
 $jsondata = json_decode($freegeoipjson);
 $countryfromip = $jsondata->country_name;
 echo "Country: ". $countryfromip ."";
?>

Fuente: Obtenga visitantes país y ciudad en PHP usando la API de ipstack


0

Esta es solo una nota de seguridad sobre la funcionalidad de get_client_ip()que la mayoría de las respuestas aquí se han incluido dentro de la función principal de get_geo_info_for_this_ip().

No confíe demasiado en los datos IP en los encabezados de la solicitud como Client-IPo X-Forwarded-Forporque pueden ser falseadas muy fácilmente, sin embargo, debe contar con la IP de origen de la conexión TCP que realmente se establece entre nuestro servidor y el cliente $_SERVER['REMOTE_ADDR']como se puede' ser engañado

$_SERVER['HTTP_CLIENT_IP'] // can be spoofed 
$_SERVER['HTTP_X_FORWARDED_FOR'] // can be spoofed 
$_SERVER['REMOTE_ADDR']// can't be spoofed 

Está bien obtener el país de la IP falsificada, pero tenga en cuenta que usar esta IP en cualquier modelo de seguridad (por ejemplo: prohibir la IP que envía solicitudes frecuentes) destruirá todo el modelo de seguridad. En mi humilde opinión, prefiero usar la IP del cliente real, incluso si es la IP del servidor proxy.


0

Tratar

  <?php
  //gives you the IP address of the visitors
  if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
      $ip = $_SERVER['HTTP_CLIENT_IP'];}
  else if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
      $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
  } else {
      $ip = $_SERVER['REMOTE_ADDR'];
  }

  //return the country code
  $url = "http://api.wipmania.com/$ip";
  $country = file_get_contents($url);
  echo $country;

  ?>

La parte if-else le dará la dirección IP del visitante y la siguiente parte le devolverá el código del país. Intente visitar api.wipmania.com y luego api.wipmania.com/[your_IP_address]
Dipanshu Mahla

0

Puede usar mi servicio: https://SmartIP.io , que proporciona nombres completos de países y ciudades de cualquier dirección IP. También exponemos zonas horarias, moneda, detección de proxy, detección de nodos TOR y detección de criptografía.

Solo necesita registrarse y obtener una clave API gratuita que permite 250,000 solicitudes por mes.

Usando la biblioteca oficial de PHP, la llamada API se convierte en:

$apiKey = "your API key";
$smartIp = new SmartIP($apiKey);
$response = $smartIp->requestIPData("8.8.8.8");

echo "\nstatus code: " . $response->{"status-code"};
echo "\ncountry name: " . $response->country->{"country-name"};

Consulte la documentación de la API para obtener más información: https://smartip.io/docs


0

A partir de 2019, MaxMind country DB se puede usar de la siguiente manera:

<?php
require_once 'vendor/autoload.php';
use MaxMind\Db\Reader;
$databaseFile = 'GeoIP2-Country.mmdb';
$reader = new Reader($databaseFile);
$cc = $reader->get($_SERVER['REMOTE_ADDR'])['country']['iso_code'] # US/GB...
$reader->close();

Fuente: https://github.com/maxmind/MaxMind-DB-Reader-php


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.