IP address to geographic details

Today I received a small project to detect the country of web visitors. I’ve never done something like that before, so as always, I started googling around. And it turned out that it’s not that complex - there is a company called MaxMind that offers APIs to look up geographic details from an IP address. The APIs are written in a variety of languages like C, Perl, Java, Python, Ruby, C#, VB.NET, Pascal, Javascript, and of course, PHP.

For this project, I decided to go with PHP version which has a NET_GeoIP PEAR package. Just download it, along with the free data files (they have paid ones also) - Geo Lite Country if you want the country details only, or Geo Lite City if you want extra stuffs like city, region, latitude and longtitude etc. In this post, I’ll go with City version.

Now, with everything downloaded and extracted into a folder, start with an empty index.php file and fill it with some code:

<?php
require_once "path/to/file/GeoIP.php";
// define a new instance of Net_GeoIP class
$geoip = Net_GeoIP::getInstance("path/to/file/GeoLiteCity.dat");
try {
    var_dump($geoip->lookupLocation($_SERVER['REMOTE_ADDR']));
} catch (Exception $e) {
    // Handle exception
}
?>

The function lookupLocation() from class NET_GeoIP accepts a string parameter in IP format - something like “210.245.17.13″ and returns a Location object which contains several useful geographic information. If you run this script on your localhost however, nothing will be printed. That is because in such a case, $_SERVER['REMOTE_ADDR'] is a local IP - most often 127.0.0.1 - which cannot tell us anything. Have you heard this quote “There is nothing like 127.0.0.1″?

So for testing purpose, let’s modify the above code a bit, so that it can accept an optional query parameter as an IP.

<?php
require_once "path/to/file/GeoIP.php";
// define a new instance of Net_GeoIP class
$geoip = Net_GeoIP::getInstance("path/to/file/GeoLiteCity.dat");
$ip = isset($_GET['test_ip']) ? $_GET['test_ip'] : $_SERVER['REMOTE_ADDR'];
try {
    var_dump($geoip->lookupLocation($ip));
} catch (Exception $e) {
    // Handle exception
}
?>

Now if you’ve set it everything correctly in place, browse to index.php?test_ip=210.124.12.3 will show something like this:

<code>object(Net_GeoIP_Location)#2 (10) {
  ["countryCode"]=&gt;
  string(2) "KR"
  ["countryName"]=&gt;
  string(18) "Korea, Republic of"
  ["region"]=&gt;
  string(2) "11"
  ["city"]=&gt;
  string(5) "Seoul"
  ["postalCode"]=&gt;
  NULL
  ["latitude"]=&gt;
  float(37.5664)
  ["longitude"]=&gt;
  float(126.9997)
  ["areaCode"]=&gt;
  NULL
  ["dmaCode"]=&gt;
  NULL
  ["countryCode3"]=&gt;
  string(3) "KOR"
}</code>

Similarly, index.php?test_ip=128.54.13.8 shows

<code>object(Net_GeoIP_Location)#2 (10) {
  ["countryCode"]=&gt;
  string(2) "US"
  ["countryName"]=&gt;
  string(13) "United States"
  ["region"]=&gt;
  string(2) "CA"
  ["city"]=&gt;
  string(8) "La Jolla"
  ["postalCode"]=&gt;
  string(5) "92093"
  ["latitude"]=&gt;
  float(32.8807)
  ["longitude"]=&gt;
  float(-117.2359)
  ["areaCode"]=&gt;
  int(858)
  ["dmaCode"]=&gt;
  float(825)
  ["countryCode3"]=&gt;
  string(3) "USA"
}</code>

Extremely useful, isn’t it? With these information on hand, there’s no limit of what we can do to improve user interaction and much more.

A simple demo of this can be found here.

  • I just stumbled across this post, and although I am all for cool technology (and I agree, this is cool), there is however just one small issue with this:
    Most people implementing this, forget to implement a manual override so that the visitor herself can change the language.

    Why would a user want to switch languages? I know two natural languages, Swedish and English. If I were to go abroad, say Germany, or Japan or wherever, and I go to a site which use geo-localization through IP, I would be unable to interact with that site. Sounds fair?

    So best bet would be to first check for existence of language setting in a cookie (or if logged in, in the user prefs), then geoIP, and finally have a manual override.

    Just my 0.02 SEK

  • The most serious problem I can see with relying on such input to deliver content is that it is rather inaccurate. For example, I live in Lodi, CA but the software returns Modesto, CA (3 cities, or about 36 miles away).
    While this isn’t a problem for delivering general content pertinent to a large area, trying to deliver targeted content (whether it be ads, news, etc.) often fails miserably. It would be wiser to wait for a system more reliable than IP addresses.

  • I totally agree. But nevertheless, they do have purchased accounts which are believed to have better accuracy.

  • Thank you for information! As I can see, it is posible to get full city data from IP adress, and in GeoLiteCity.dat we have full world city datubase, but in HEX. So I vere thinking, is there any posible way to get city data from other Variables, like latitude or country name?
     
    Why am I asking this - because I’m interested to get datubase with city names , long and lat for my web page!
    Thank you!

  • @Patrik
    Yes, I see you point, but I don’t think this tool is mainly used for language detection (without a backup system … (cookies, prefs, navigation))

    But to control the content of your site - it’s perfect. Advertisment, and to use with GoogleMaps (getting the coordinates). With the location you can then script something to get/filter the timezone.

    You can also BLOCK content like a stream of a video IN your country, but not countries outside (due to permissions/regulations). Both YouTube an NHL.com use that technique to block the content I like to see sometimes. :)

    Is more than just languages…

    Just my 2,00 SEK ;)

You can follow any responses to this entry through the RSS 2.0 feed.

Trackbacks / Pingbacks