miércoles, 25 de julio de 2012

Detectar País, Región , Ciudad, Latitud , Zona horaria dado el IP de un cliente web. Código PHP




Una buena práctica en sitios web que necesiten registro de usuario es detectar el país y otros datos que pueden ser útiles aportando valor agregado y seguridad a su web .


¿Cómo detectar el IP real de un usuario que entra a su web?

Este código está en montones de páginas, lo comparto con ustedes en la clase que verán más adelante : método es getRealIP() de la clase IPLocalizador.


¿Cómo determinar dado el IP de un cliente , datos como: país , zona , ciudad , coordenadas , zona horaria?

Para ello podemos hacer uso de alguna API en internet que brinde el servicio gratis. Yo en este caso recomiendo usar el API que proporciona la web: www.ipinfodb.com

Paso 1: Registrarse en la web (http://www.ipinfodb.com/register.php) al registrarse y confirmar , obtienes una llave, esta llave no es más que un código que te identifica para hacer distintas consultas.

Ahora solo tenemos que hacer envíos al API de la siguiente manera:

http://api.ipinfodb.com/v3/ip-city/?key={llave}&ip={IP}


Como se puede ver en la URL anterior, se pasa de forma obligatoria key y ip. De forma opcional se pueden pasar los siguientes parámetros:


Parámetro
Valor por defecto
Posibles valores y significado
format  
raw
raw =>  Formato texto separado por punto y coma
xml => Formato XML
json => Formato  json



 Comparto con ustedes las siguientes clases usadas en un proyecto desarrollado por Moises Soft:


class IPLocalizadorData{
   var $statusCode; // estado de los datos
   var $ipAddress;   // IP
   var $countryCode;  // Código de 2 caracteres del país
   var $countryName;   // Nombre del país en Inglés
   var $regionName;    // nombre de la región
   var $cityName;      // nombre de la ciudad
   var $zipCode;       // código postal
   var $latitude;      // latitud
   var $longitude;     // Longitud
   var $timeZone;      // Zona horaria
}


class IPLocalizador {
     /**
     *
     * @param string $ip
     * @param string $key
     * @return IPLocalizadorData
     */
    static function getData($ip,$key)
    {
       if (!$ip) $ip = self::getRealIP();


        if (!$key)
        $key = "su llave";
        $response =   file_get_contents("http://api.ipinfodb.com/v3/ip-city/?key=$key&ip=$ip&format=raw");

       $part = split(";", $response);

       $r = new IPLocalizadorData();
       $r->statusCode = $part[0];
       $r->ipAddress = $part[2];
       $r->countryCode = $part[3];
       $r->countryName = $part[4];
       $r->regionName = $part[5];
       $r->cityName = $part[6];
       $r->zipCode = $part[7];
       $r->latitude = $part[8];
       $r->longitude = $part[9];
       $r->timeZone = $part[10];

       return  $r; 
    }

static  function getRealIP()
{

   if( $_SERVER['HTTP_X_FORWARDED_FOR'] != '' )
   {
      $client_ip =
         ( !empty($_SERVER['REMOTE_ADDR']) ) ?
            $_SERVER['REMOTE_ADDR']
            :
            ( ( !empty($_ENV['REMOTE_ADDR']) ) ?
               $_ENV['REMOTE_ADDR']
               :
               "unknown" );

      // los proxys van añadiendo al final de esta cabecera
      // las direcciones ip que van "ocultando". Para localizar la ip real
      // del usuario se comienza a mirar por el principio hasta encontrar
      // una dirección ip que no sea del rango privado. En caso de no
      // encontrarse ninguna se toma como valor el REMOTE_ADDR

      $entries = split('[, ]', $_SERVER['HTTP_X_FORWARDED_FOR']);

      reset($entries);
      while (list(, $entry) = each($entries))
      {
         $entry = trim($entry);
         if ( preg_match("/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/", $entry, $ip_list) )
         {
            // http://www.faqs.org/rfcs/rfc1918.html
            $private_ip = array(
                  '/^0\./',
                  '/^127\.0\.0\.1/',
                  '/^192\.168\..*/',
                  '/^172\.((1[6-9])|(2[0-9])|(3[0-1]))\..*/',
                  '/^10\..*/');

            $found_ip = preg_replace($private_ip, $client_ip, $ip_list[1]);

            if ($client_ip != $found_ip)
            {
               $client_ip = $found_ip;
               break;
            }
         }
      }
   }
   else
   {
      $client_ip =
         ( !empty($_SERVER['REMOTE_ADDR']) ) ?
            $_SERVER['REMOTE_ADDR']
            :
            ( ( !empty($_ENV['REMOTE_ADDR']) ) ?
               $_ENV['REMOTE_ADDR']
               :
               "unknown" );
   }

   return $client_ip;

}

}


De modo que usted llamando al método getData($ip,$key) de la clase IPLocalizador, puede obtener un objeto de la clase IPLocalizadorData , con toda la información que inicialmente deseábamos obtener.


Limitantes de la API

Esta API es gratis , y solo dejará hacer 2 consultas por segundo , por lo que es muy recomendado solo hacer la consulta 1 vez y almacenar la información en las variables de sección , cookies o base de dato.

No hay comentarios:

Publicar un comentario