GeoIP query

Looks up location data for an IP address from a portable, compact database. Uses data from MaxMind GeoIP or GeoLite.

If you want to determine the approximate location of a website visitor without using the browser’s location API or asking the user, you may also use their IP address. The company MaxMind maintains such a database that maps IP addresses to countries and localities. So depending on the resolution of the database being used, you can locate the user with some probability down to a few tens of kilometres. MaxMind offers this database for free under the name GeoLite. The commercial version is GeoIP and it contains more address details and is more accurate in some countries.

Depending on the resolution, the data size can get quite large. The CSV raw data for country-level resolution is currently almost 10 MB, city-level resolution is already 90 MB. MaxMind also offers a proprietary binary format, that makes 1.2 MB and 18 MB. But their file format is obscure and the provided access library for PHP is bulky and obscure as well. So I, like a few others as it seems, have decided to use my own optimised binary format.

All data in this format is stored in several tables, sorted in fixed-length records. That allows for an efficient binary search for the desired IP address. That is exactly how large database servers do it. Additional text data like the city or country name is stored subsequently and every address range entry holds a direct pointer to that string. That is roughly a simple description of my file format. One query takes 1-2 milliseconds on average-slow hardware. IPv4 and IPv6 addresses as well as all required text labels are combined in a single file that is divided in multiple sections. There is a smaller file with country data (800 kB) and a larger one with city data (20 MB). So my format is considerably more storage space efficient than MaxMind’s for country data, and only slightly larger for city data.

The query access class is only available for PHP. Porting to other languages should be easy because of the clear and simple code. While I used a PHP script for generating the database in a previous version, there is only a C# application right now. That is a lot faster. The conversion of all files takes about 20 seconds on my computer (in contrast to 5 minutes). This conversion tool is also available so that you can update the database yourself from MaxMind’s data.

Compatibility: PHP Version 5.0 or newer

Example

The following sample code demonstrates querying the visitor’s location:

require_once 'lib/geoip.class.php';

// If the database files are not stored in the same directory as the GeoIP class, then
// the path to them must be specified. The files are named geolitecountry.bin and
// geolitecity.bin.
GeoIP::SetDBFileName('/path/to/database-files');

// Use the IP address of the web visitor
$ipAddress = $_SERVER['REMOTE_ADDR'];

// The query is performed with a single static method call. Only the requested IP
// address is passed. IPv4 and IPv6 are equally accepted. The return value is an array
// containing the found location data. The availability of the fields depends on the
// used database edition. The city database is used first. If it does not exist, then
// the country database is used.
// ----------------
// This is the essential call:
$data = GeoIP::LookupIP($ipAddress);
// ----------------

// The country code is practically always available as long as the address is covered
// by the database. Example: DE, GB, US, JP
$countryCode = $data['cc'];
// Name of the region, province or state, in local language and latin text (7 bit ASCII).
// Example: Bayern, Baden-Wurttemberg, Kent, Catalonia, Mississippi
$region = $data['region'];
// Name of the city, town or village. This can be anything from a world city to a rural
// hamlet. Often in local language, in latin text.
$city = strlen($data['city']) ? utf8_encode($data['city']) : null;
// Latitude and longitude of the location. Relatively precise for cities, somewhere in
// the middle aligned to the grid for regions or countries only.
$lat = $data['lat'];
$lng = $data['lng'];

Download

The first download contains the access library that is required for resolving IP addresses:

geoip.class.php12.9 KiBSource code of the GeoIP class for location queries in PHP

You also need a converted database to use the class. The files provided here may not be current at all times. You only need either one, the larger file contains the smaller one.

geolitecountry-201310.7z205 KiBGeoLite database with country resolution, from 2013-10

geolitecity-201310.7z8.2 MiBGeoLite database with city resolution, from 2013-10

The following files are intended for developers of this class or to convert newer databases:

geoip_test.7z1.0 KiBPHP test scripts for testing the access library (from end of 2012)

GeoIPConverter.7z22.2 KiBDatabase converter (C# project and compiled application)

TODO: Verwendung des C#-Konverters beschreiben

Licence and terms of use

This software is released under the terms of the GNU GPL licence, version 3. You can find the detailed terms and conditions in the download or on the GNU website.

Different licence terms apply to the GeoLite databases, you can read them here. This product includes GeoLite data created by MaxMind, available from http://maxmind.com/.

Statistic data

  • Created on 2012-11-16, updated on 2012-11-17.
  • First used in tòmò web analytics.
  • Ca. 1 120 lines of code, estimated development costs: 1 100 - 4 500 €