Location detecting techniques for IP addresses

依然范特西╮ 提交于 2019-11-27 01:44:45
Tim Jansen

You can't do this without a database that maps IP addresses to cities/countries/providers. There are commercial offerings such as ip2location that you could use. AFAIK there is no free alternative though, as maintaining such a IP database is quite a lot of work. Free alternative: GeoIP2

Update: There are several things that allow you to create such a db, if you invest enough time:

  1. Use the databases provided by regional and local registries to find an IP's owner.
  2. Many ISPs use a naming schema that allows you to locate the user. Sometimes you can even read the city name in plain text if you do a reverse-DNS lookup. Sometimes it is more cryptic. For example I currently have p5dcf6c4a.dip.t-dialin.net , and I have no idea that the naming scheme is..
  3. Use a traceroute. If you can't identify the location of a user, you can still find out the location of its uplink

If you looking for some copy - paste solution, i foudn this code :

    function countryCityFromIP($ipAddr)
{
//function to find country and city from IP address
//Developed by Roshan Bhattarai http://roshanbh.com.np

//verify the IP address for the
ip2long($ipAddr)== -1 || ip2long($ipAddr) === false ? trigger_error("Invalid IP", E_USER_ERROR) : "";
$ipDetail=array(); //initialize a blank array

//get the XML result from hostip.info
$xml = file_get_contents("http://api.hostip.info/?ip=".$ipAddr);

//get the city name inside the node <gml:name> and </gml:name>
preg_match("@<Hostip>(\s)*<gml:name>(.*?)</gml:name>@si",$xml,$match);

//assing the city name to the array
$ipDetail['city']=$match[2]; 

//get the country name inside the node <countryName> and </countryName>
preg_match("@<countryName>(.*?)</countryName>@si",$xml,$matches);

//assign the country name to the $ipDetail array
$ipDetail['country']=$matches[1];

//get the country name inside the node <countryName> and </countryName>
preg_match("@<countryAbbrev>(.*?)</countryAbbrev>@si",$xml,$cc_match);
$ipDetail['country_code']=$cc_match[1]; //assing the country code to array

//return the array containing city, country and country code
return $ipDetail;

}

Hope this helps somebody.

There are databases (some of them are free of charge) which can be used to convert IP's into Cities:

eg: http://www.maxmind.com/app/geolitecity

You can map an IP address to its location (city, country, postal code), timezone etc. with either a database or an API (hosted database).

Here's an example of using an API

curl https://ipapi.co/city/ 
> Mountain View

curl https://ipapi.co/country/
> US

curl https://ipapi.co/timezone/
> America/Los_Angeles 

more here : Location from IP address

Instead of using third party API I would suggest you to use self hosted IP record. This post explain you more

http://www.techsirius.com/2014/05/simple-geo-tracking-system.html

Basically they are using maxmind's country city IP database record [http://dev.maxmind.com/geoip/geoip2/geolite2/] with few modifications. After that a sample query

$ip =  $_SERVER['REMOTE_ADDR'];
$long = sprintf('%u', ip2long($ip));
$sql = "SELECT * FROM `geo_ips` WHERE '$long' BETWEEN `ip_start` AND `ip_end`";

U can use this function

 function ip_info(){
            return $data = json_decode(file_get_contents('http://ip-api.com/json/'),true);
        }

Call the function

$info = ip_info();
var_dump($info);

One way in which these databases are compiled is from whois information. For example, to determine the location of 69.59.196.211:

fmark@home:~$ host 69.59.196.211 211.196.59.69.in-addr.arpa domain name pointer stackoverflow.com. fmark@home:~$ whois stackoverflow.com

Whois Server Version 2.0

Domain names in the .com and .net domains can now be registered with many different competing registrars.

 <SNIP>

> Registrant: stackoverflow.com llc
410 Clayton Ave El Cerrito, California 94530 United States

 <SNIP>

Obviously this isn't hugely accurate, so more sophisticated techniques are allegedly used.

If the geolocation functionality is not a big requirement for your project, you can use something as simple as this:

$geotxt='';
$dt=json_decode(@file_get_contents('https://freegeoip.net/json/'.$_SERVER['REMOTE_ADDR']));
if ($dt!=null) $geotxt=$dt->country_name.', '.$dt->region_name.', '.$dt->city;
echo $geotxt;

You have to take into account that freegeoip has a limit of 10k request/hour.

Jonathan

Most of the existing databases use an aggregation of data from the international registries ARIN, AFRINIC, ANIC etc as well as user submitted locations. More sophisticated techniques include Topology and Constraints Geolocation.

I run my own API ipdata.co that provides several data points including, the country, city, region, lat/long and others.

This answer uses a 'test' API Key that is very limited and only meant for testing a few calls. Signup for your own Free API Key and get up to 1500 requests daily for development.

php > $data = json_decode(file_get_contents('https://api.ipdata.co/69.59.196.211?api-key=test'),true);
php > echo $data['country_name'];
//United States
php > echo $data['city'];
//Albany
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!