Clase para geolocalizar la IP en PHP + Google Maps API
En el proyecto pidecita.com del iWeekend de Valencia se hacía uso de Google Maps para localizar las peluquerías, y se pensó en recomendar varias al usuario en base a su ubicación. Para ello implementé una clase muy básica en PHP para geolocalizar la IP del usuario consumiendo la API de hostip.
Existen muchos servicios que ofrecen información sobre el país en el que te encuentras, pero lo que nosotros queríamos era localizar por ciudad. Este tipo de servicios suele acertar el país en un 95% de los casos, pero la provincia o ciudad no suele ser la correcta sino la del proxy de tu proveedor. Se basa en rangos de IP específicamente asignados a cada país, por lo que su fiabilidad en este sentido es media/baja. Mi IP estática que me brinda Telefónica me localiza mi provincia perfectamente, además de sus coordenadas.
Con la API REST de Hostip pódeis hacer las siguientes consultas:
http://api.hostip.info/country.php US http://api.hostip.info/get_html.php?ip=12.215.42.19 Country: UNITED STATES (US) City: Sugar Grove, IL http://api.hostip.info/get_html.php?ip=12.215.42.19&position=true Country: UNITED STATES (US) City: Sugar Grove, IL Latitude: 41.7696 Longitude: -88.4588 http://api.hostip.info/?ip=12.215.42.19 [Archivo XML]
En un principio en el iWeekend parseaba el html devuelto de la 2º opción, pero ya de paso para probar la facilidad que te brinda PHP 5 para leer XML con Simple XML he utilizado la 4º opción. La clase es muy fácil de usar sólo tenéis que incluirla y llamar al método getLocationFromIp():
include('./classes/geoLocateIp.class.php'); $geo = new geoLocateIp(); $location = $geo -> getLocationFromIp(); |
La variable $location es un array asociativo con los siguientes campos: CountryName, CountryCode, City, Longitude y Latitude.
Os dejo el código fuente de la clase:
class geoLocateIp { private $serviceLocateURL = 'http://api.hostip.info/?ip='; public function getLocationFromIp() { $ip = $this->getIpAdress(); if (empty($ip)) throw new Exception('Error retrieving IP address'); // Use the method your server supports ( most of them only support curl ) $xmlData = geoLocateIp::file_get_contents_curl($this->serviceLocateURL.$ip); //$xmlData = file_get_contents($this->serviceLocateURL.$ip); if (empty($xmlData)) throw new Exception('Error retrieving xml'); $locationInfo = $this->parseLocationData($xmlData); return $locationInfo; } private function getIpAdress() { if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; } elseif (isset($_SERVER['HTTP_VIA'])) { $ip = $_SERVER['HTTP_VIA']; } elseif (isset($_SERVER['REMOTE_ADDR'])) { $ip = $_SERVER['REMOTE_ADDR']; } else { $ip = NULL; } return $ip; } private function parseLocationData($xmlData) { // Use of Simple XML extension of PHP 5 $xml = simplexml_load_string($xmlData); if (!is_object($xml)) throw new Exception('Error reading XML'); $infoHost = $xml->xpath('//gml:featureMember'); $city = $xml->xpath('//gml:featureMember//gml:name'); $coordinates = $infoHost[0]->xpath('//gml:coordinates'); $coordinates = split(',', (string) $coordinates[0]); $info = array ( "City" => (string) $city[0], "CountryName" => (string) $infoHost[0]->Hostip->countryName, "CountryCode" => (string) $infoHost[0]->Hostip->countryAbbrev, "Longitude" => $coordinates[0], "Latitude" => $coordinates[1] ); return $info; } public static function file_get_contents_curl($url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_URL, $url); $data = curl_exec($ch); curl_close($ch); return $data; } } |
Y a continuación, he preparado un mashup muy básico con dicha clase y la API de Google Maps en el que geolocaliza en el mapa tu situación. Lo he llamado Geolocate your IP, original verdad? : ) Estoy abierto a críticas del código, bugs, chapuzas… Y si queréis el código fuente sólo tenéis que decírmelo.
Update: Por una petición masiva de Darocz dejo el código fuente del mini-mashup y el de la clase geoLocateIp.
Tags: api, geolocalizar ip, google maps, hostip, php, script, simple xml