209

I want to retrieve information like the city, state, and country of a visitor from their IP address, so that I can customize my web page according to their location. Is there a good and reliable way to do this in PHP? I am using JavaScript for client-side scripting, PHP for server-side scripting, and MySQL for the database.

Ben Dowling
  • 17,187
  • 8
  • 87
  • 103

20 Answers20

265

You could download a free GeoIP database and lookup the IP address locally, or you could use a third party service and perform a remote lookup. This is the simpler option, as it requires no setup, but it does introduce additional latency.

One third party service you could use is mine, http://ipinfo.io. They provide hostname, geolocation, network owner and additional information, eg:

$ curl ipinfo.io/8.8.8.8
{
  "ip": "8.8.8.8",
  "hostname": "google-public-dns-a.google.com",
  "loc": "37.385999999999996,-122.0838",
  "org": "AS15169 Google Inc.",
  "city": "Mountain View",
  "region": "CA",
  "country": "US",
  "phone": 650
}

Here's a PHP example:

$ip = $_SERVER['REMOTE_ADDR'];
$details = json_decode(file_get_contents("http://ipinfo.io/{$ip}/json"));
echo $details->city; // -> "Mountain View"

You can also use it client-side. Here's a simple jQuery example:

$.get("https://ipinfo.io/json", function (response) {
    $("#ip").html("IP: " + response.ip);
    $("#address").html("Location: " + response.city + ", " + response.region);
    $("#details").html(JSON.stringify(response, null, 4));
}, "jsonp");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h3>Client side IP geolocation using <a href="http://ipinfo.io">ipinfo.io</a></h3>

<hr/>
<div id="ip"></div>
<div id="address"></div>
<hr/>Full response: <pre id="details"></pre>
Ben Dowling
  • 17,187
  • 8
  • 87
  • 103
  • 1
    You may want to make sure you add a json on the end of the URL to ensure you get json back instead of the full web page. $details = json_decode(file_get_contents("http://ipinfo.io/{$ip}/json")); – Doug Dec 21 '13 at 02:57
  • You get JSON without adding /json too if you're requesting it from PHP and not a web browser – Ben Dowling Dec 21 '13 at 06:44
  • Not always. I got back the web page and I ran it from PHP. – Doug Dec 21 '13 at 14:47
  • 3
    Doesn't seem like a very reliable service. I'm getting `null` for my city name. It's not like a small city or something but it still couldn't locate it. If it doesn't work well within US, I doubt how often it will also return null outside US. – Derek 朕會功夫 Oct 07 '14 at 23:00
  • Remove the $ip line and instead use just 'http://ipinfo.io/". The service is now intuitive enough to figure out the rest, and $details->city echoes correctly. – Isaac Askew Nov 12 '14 at 17:41
  • @BenDowling According to your example and jsfiddle, it seems that we can use `ipinfo.io` without any login/password, or am I wrong? Then, how can you check if my website did more 10'000 daily requests, and would require a paid plan? – Basj Apr 24 '16 at 12:46
  • Yes that's right. We enforce the 1,000 (not 10,000) limit per day based on a number of different factors including the requesting IP, requesting domain. Paid plans all come with an access token though. – Ben Dowling Apr 25 '16 at 13:53
  • 2
    the result is not accurate .. region, city postal – Mark Gerryl Mirandilla Oct 26 '16 at 00:48
  • 2
    WARNING: As of Jan/2019, some people reported that this **ipinfo** url is _unsafe_ on virustotal, due to trojan. The votes were between 2015 and 2018 – Ricardo Jan 03 '19 at 00:50
  • 1
    It was incorrectly added via this change https://github.com/easylist/easylist/commit/afb614087c0848e648f25054e189796513cdc1d5#diff-dbc51871bdd5cf7971a65ef9684d2248R2781 - we're working on getting it removed. There's nothing unsafe about ipinfo.io though. – Ben Dowling Jan 08 '19 at 17:40
  • @BenDowling for some reason https://ipinfo.io/json doesn't load at all, after 3.5 min timeout – Rashmi Kumari Oct 29 '20 at 19:48
55

Thought I'd post as nobody seems to have given info on this particular API, but its returning exactly what I'm after and you can get it to return in multiple formats, json, xml and csv.

 $location = file_get_contents('http://freegeoip.net/json/'.$_SERVER['REMOTE_ADDR']);
 print_r($location);

This will give you all of the things you could possibly want:

{
      "ip": "77.99.179.98",
      "country_code": "GB",
      "country_name": "United Kingdom",
      "region_code": "H9",
      "region_name": "London, City of",
      "city": "London",
      "zipcode": "",
      "latitude": 51.5142,
      "longitude": -0.0931,
      "metro_code": "",
      "areacode": ""

}
Jamie Hutber
  • 26,790
  • 46
  • 179
  • 291
24

A pure Javascript example, using the services of https://geolocation-db.com They provide a JSON and JSONP-callback solution.

No jQuery required!

<!DOCTYPE html>
<html>
<head>
<title>Geo City Locator by geolocation-db.com</title>
</head>
<body>
    <div>Country: <span id="country"></span></div>
    <div>State: <span id="state"></span></div>
    <div>City: <span id="city"></span></div>
    <div>Postal: <span id="postal"></span></div>
    <div>Latitude: <span id="latitude"></span></div>
    <div>Longitude: <span id="longitude"></span></div>
    <div>IP address: <span id="ipv4"></span></div>                             
</body>
<script>

    var country = document.getElementById('country');
    var state = document.getElementById('state');
    var city = document.getElementById('city');
    var postal = document.getElementById('postal');
    var latitude = document.getElementById('latitude');
    var longitude = document.getElementById('longitude');
    var ip = document.getElementById('ipv4');

    function callback(data)
    {
        country.innerHTML = data.country_name;
        state.innerHTML = data.state;
        city.innerHTML = data.city;
        postal.innerHTML = data.postal;
        latitude.innerHTML = data.latitude;
        longitude.innerHTML = data.longitude;
        ip.innerHTML = data.IPv4;
    }

    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'https://geolocation-db.com/json/geoip.php?jsonp=callback';
    var h = document.getElementsByTagName('script')[0];
    h.parentNode.insertBefore(script, h);

</script> 
</html>
Makyen
  • 31,849
  • 12
  • 86
  • 121
Kurt Van den Branden
  • 11,995
  • 10
  • 76
  • 85
16

Using Google APIS:

<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script>
contry_code = google.loader.ClientLocation.address.country_code
city = google.loader.ClientLocation.address.city
region = google.loader.ClientLocation.address.region
</script>
Raposo
  • 499
  • 5
  • 4
  • 9
    `The geolocation functionality in the Loader hasn't been retired, per se. We stopped documenting it several years ago and have recommended the HTML-based solutions due to their improved accuracy, but the functionality itself has not been removed from the Loader at this time.` http://code.google.com/p/google-ajax-apis/issues/detail?id=586 – TheFrost Aug 28 '13 at 00:15
  • What about the quality of this Google APIS IP geolocation? (it is, or am I wrong?), compared to other services such as http://www.ipinfo.io? – Basj Apr 24 '16 at 12:43
  • I asked to ~ 30 people in different cities, and Google APIS IP geolocation quality is poor compared to ipinfo.io – Basj Apr 24 '16 at 21:10
  • 1
    @Basj Google API works like a charm while ipinfo.io shows I'm in US while I'm actually in the central Europe – patryk Feb 20 '17 at 20:01
15

I wrote a bot using an API from ipapi.co, here's how you can get location for an IP address (e.g. 1.2.3.4) in php :

Set header :

$opts = array('http'=>array('method'=>"GET", 'header'=>"User-Agent: mybot.v0.7.1"));
$context = stream_context_create($opts);

Get JSON response

echo file_get_contents('https://ipapi.co/1.2.3.4/json/', false, $context);

of get a specific field (country, timezone etc.)

echo file_get_contents('https://ipapi.co/1.2.3.4/country/', false, $context);
Jaimes
  • 347
  • 3
  • 5
15

You need to use an external service... such as http://www.hostip.info/ if you google search for "geo-ip" you can get more results.

The Host-IP API is HTTP based so you can use it either in PHP or JavaScript depending on your needs.

null
  • 7,432
  • 4
  • 26
  • 28
  • 6
    I have been using hostip.info for a year now and I'm NOT impressed. It usually return unknown 9/10 checks – aron Jun 30 '10 at 14:32
  • agreed, its telling me i live in Woking... In fairness it got the GB bit right... But I'm in London. – Jamie Hutber May 16 '13 at 14:02
  • 2
    Keep in mind any service is only going to be as good as the public info/data available. Due to privacy reasons this info can only be "so good". If it gets your country right, and at least close on the state/province, I'd consider that a WIN. If you happen to be using this to look-up info for a DOS attack, keep in mind the IPs might not even be valid (not assigned to anyone or outside valid public IP range). – eselk Apr 16 '14 at 19:32
  • On their website I get "Location: ... actually we haven't a clue.". All I needed to know – Bojan Kogoj Feb 15 '16 at 14:07
10

This question is protected, which I understand. However, I do not see an answer here, what I see is a lot of people showing what they came up with from having the same question.

There are currently five Regional Internet Registries with varying degrees of functionality that serve as the first point of contact with regard to IP ownership. The process is in flux, which is why the various services here work sometimes and don't at other times.

Who Is is (obviously) an ancient TCP protocol, however -- the way it worked originally was by connection to port 43, which makes it problematic getting it routed through leased connections, through firewalls...etc.

At this moment -- most Who Is is done via RESTful HTTP and ARIN, RIPE and APNIC have RESTful services that work. LACNIC's returns a 503 and AfriNIC apparently has no such API. (All have online services, however.)

That will get you -- the address of the IP's registered owner, but -- not your client's location -- you must get that from them and also -- you have to ask for it. Also, proxies are the least of your worries when validating the IP that you think is the originator.

People do not appreciate the notion that they are being tracked, so -- my thoughts are -- get it from your client directly and with their permission and expect a lot to balk at the notion.

jinzai
  • 436
  • 3
  • 9
8

The service in Ben Dowling's response has changed, so it's now simpler. To find the location, simply do:

// no need to pass ip any longer; ipinfo grabs the ip of the person requesting
$details = json_decode(file_get_contents("http://ipinfo.io/"));
echo $details->city; // city

The coordinates return in a single string like '31,-80', so from there you just:

$coordinates = explode(",", $details->loc); // -> '31,-89' becomes'31','-80'
echo $coordinates[0]; // latitude
echo $coordinates[1]; // longitude
Isaac Askew
  • 1,281
  • 2
  • 17
  • 30
  • 4
    You're right that http://ipinfo.io will return the details for the caller's IP by default. If you're running a PHP website that'll be your server's IP though, rather than the user's IP. That's the reason why you need to pass in $_SERVER['REMOTE_ADDR']. If you just want coordinates it'll be quicker to append /loc to the URL to get just that field too. – Ben Dowling Nov 15 '14 at 23:58
8

Look at the API from hostip.info - it provides lots of information.
Example in PHP:

$data = file_get_contents("http://api.hostip.info/country.php?ip=12.215.42.19");
//$data contains: "US"

$data = file_get_contents("http://api.hostip.info/?ip=12.215.42.19");
//$data contains: XML with country, lat, long, city, etc...

If you trust hostip.info, it seems to be a very useful API.

Isaac Waller
  • 32,709
  • 29
  • 96
  • 107
8

I like the free GeoLite City from Maxmind which works for most applications and from which you can upgrade to a paying version if it's not precise enough. There is a PHP API included, as well as for other languages. And if you are running Lighttpd as a webserver, you can even use a module to get the information in the SERVER variable for every visitor if that's what you need.

I should add there is also a free Geolite Country (which would be faster if you don't need to pinpoint the city the IP is from) and Geolite ASN (if you want to know who owns the IP) and that finally all these are downloadable on your own server, are updated every month and are pretty quick to lookup with the provided APIs as they state "thousands of lookups per second".

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
lpfavreau
  • 12,871
  • 5
  • 32
  • 36
  • 1
    You can consider the IP2Location LITE http://lite.ip2location.com which is free. It has up to ZIP code information which is very useful. – Michael C. Nov 16 '14 at 00:59
8

I run the service at IPLocate.io, which you can hook into for free with one easy call:

<?php
$res = file_get_contents('https://www.iplocate.io/api/lookup/8.8.8.8');
$res = json_decode($res);

echo $res->country; // United States
echo $res->continent; // North America
echo $res->latitude; // 37.751
echo $res->longitude; // -97.822

var_dump($res);

The $res object will contain your geolocation fields like country, city, etc.

Check out the docs for more information.

ttarik
  • 3,824
  • 1
  • 32
  • 51
7

Assuming you want to do it yourself and not rely upon other providers, IP2Nation provides a MySQL database of the mappings which are updated as the regional registries change things around.

James Cape
  • 704
  • 3
  • 11
  • I was using an external service and suddenly my website became really slow. The external service was taking a good 20 seconds to send back the information - which is obviously disasterous for visitors. So decided to do it myself, and this is a perfect solution. Thank so much. – Williamz902 Nov 23 '18 at 11:45
6

In case anyone stumbles upon this thread, here's another solution. At timezoneapi.io you can request an IP address and get several objects in return (I've created the service). It was created because I needed to know which timezone my users were in, where in the world and what time it currently is.

In PHP - returns location, timezone and date/time:

// Get IP address
$ip_address = getenv('HTTP_CLIENT_IP') ?: getenv('HTTP_X_FORWARDED_FOR') ?: getenv('HTTP_X_FORWARDED') ?: getenv('HTTP_FORWARDED_FOR') ?: getenv('HTTP_FORWARDED') ?: getenv('REMOTE_ADDR');

// Get JSON object
$jsondata = file_get_contents("http://timezoneapi.io/api/ip/?" . $ip_address);

// Decode
$data = json_decode($jsondata, true);

// Request OK?
if($data['meta']['code'] == '200'){

    // Example: Get the city parameter
    echo "City: " . $data['data']['city'] . "<br>";

    // Example: Get the users time
    echo "Time: " . $data['data']['datetime']['date_time_txt'] . "<br>";

}

Using jQuery:

// Get JSON object
$.getJSON('https://timezoneapi.io/api/ip', function(data){

    // Request OK?
    if(data.meta.code == '200'){

        // Log
        console.log(data);

        // Example: Get the city parameter
        var city = data.data.city;
        alert(city);

        // Example: Get the users time
        var time = data.data.datetime.date_time_txt;
        alert(time);

    }

});
Michael Nilsson
  • 312
  • 2
  • 4
6

Ipdata.co is a fast, highly available IP Geolocation API with reliable performance.

It's extremely scalable with 10 endpoints around the world each able to handle >10,000 requests per second!

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.

In php

php > $ip = '8.8.8.8';
php > $details = json_decode(file_get_contents("https://api.ipdata.co/{$ip}?api-key=test"));
php > echo $details->region;
California
php > echo $details->city;
Mountain View
php > echo $details->country_name;
United States
php > echo $details->latitude;
37.751

Here's a client-side example showing how you'd get the country, region and city;

$.get("https://api.ipdata.co?api-key=test", function (response) {
 $("#response").html(JSON.stringify(response, null, 4));
  $("#country").html('Country: ' + response.country_name);
  $("#region").html('Region ' + response.region);
  $("#city").html('City' + response.city);  
}, "jsonp");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="country"></div>
<div id="region"></div>
<div id="city"></div>
<pre id="response"></pre>

Disclaimer;

I built the service.

For examples in multiple languages see the Docs

Also see this detailed analysis of the best IP Geolocation APIs.

Jonathan
  • 10,792
  • 5
  • 65
  • 85
6

PHP has an extension for that.

From PHP.net:

The GeoIP extension allows you to find the location of an IP address. City, State, Country, Longitude, Latitude, and other information as all, such as ISP and connection type can be obtained with the help of GeoIP.

For example:

$record = geoip_record_by_name($ip);
echo $record['city'];
Ian Hunter
  • 9,466
  • 12
  • 61
  • 77
  • 4
    This is just a php module for the MaxMind database, which is payware. (Free "lite" versions are highly inaccurate.) Not saying it is a bad thing, but it's really only useful for commercial purposes. – Mantriur Mar 19 '12 at 00:33
5

If you need to get location from an IP address you can use reliable geo ip service, you can get more detail here. It supports IPv6.

As a bonus it allows to check whether ip address is a tor node, public proxy or spammer.

You can use javascript or php as below.

Javascript Code:

$(document).ready(function () {
        $('#btnGetIpDetail').click(function () {
            if ($('#txtIP').val() == '') {
                alert('IP address is reqired');
                return false;
            }
            $.getJSON("http://ip-api.io/json/" + $('#txtIP').val(),
                 function (result) {
                     alert('City Name: ' + result.city)
                     console.log(result);
                 });
        });
    });

Php Code:

$result = json_decode(file_get_contents('http://ip-api.io/json/64.30.228.118'));
var_dump($result);

Output:

{
"ip": "64.30.228.118",
"country_code": "US",
"country_name": "United States",
"region_code": "FL",
"region_name": "Florida",
"city": "Fort Lauderdale",
"zip_code": "33309",
"time_zone": "America/New_York",
"latitude": 26.1882,
"longitude": -80.1711,
"metro_code": 528,
"suspicious_factors": {
"is_proxy": false,
"is_tor_node": false,
"is_spam": false,
"is_suspicious": false
}
Vindhyachal Kumar
  • 1,713
  • 2
  • 23
  • 27
4

The following is a modified version of a snippet I found that uses http://ipinfodb.com/ip_locator.php to get its information. Keep in mind, you can also apply for an API key with them and use the API directly to get the information supplied as you see fit.

Snippet

function detect_location($ip=NULL, $asArray=FALSE) {
    if (empty($ip)) {
        if (!empty($_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; }
        elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; }
        else { $ip = $_SERVER['REMOTE_ADDR']; }
    }
    elseif (!is_string($ip) || strlen($ip) < 1 || $ip == '127.0.0.1' || $ip == 'localhost') {
        $ip = '8.8.8.8';
    }

    $url = 'http://ipinfodb.com/ip_locator.php?ip=' . urlencode($ip);
    $i = 0; $content; $curl_info;

    while (empty($content) && $i < 5) {
        $ch = curl_init();
        $curl_opt = array(
            CURLOPT_FOLLOWLOCATION => 1,
            CURLOPT_HEADER => 0,
            CURLOPT_RETURNTRANSFER  => 1,
            CURLOPT_URL => $url,
            CURLOPT_TIMEOUT => 1,
            CURLOPT_REFERER => 'http://' . $_SERVER['HTTP_HOST'],
        );
        if (isset($_SERVER['HTTP_USER_AGENT'])) $curl_opt[CURLOPT_USERAGENT] = $_SERVER['HTTP_USER_AGENT'];
        curl_setopt_array($ch, $curl_opt);
        $content = curl_exec($ch);
        if (!is_null($curl_info)) $curl_info = curl_getinfo($ch);
        curl_close($ch);
    }

    $araResp = array();
    if (preg_match('{<li>City : ([^<]*)</li>}i', $content, $regs)) $araResp['city'] = trim($regs[1]);
    if (preg_match('{<li>State/Province : ([^<]*)</li>}i', $content, $regs)) $araResp['state'] = trim($regs[1]);
    if (preg_match('{<li>Country : ([^<]*)}i', $content, $regs)) $araResp['country'] = trim($regs[1]);
    if (preg_match('{<li>Zip or postal code : ([^<]*)</li>}i', $content, $regs)) $araResp['zip'] = trim($regs[1]);
    if (preg_match('{<li>Latitude : ([^<]*)</li>}i', $content, $regs)) $araResp['latitude'] = trim($regs[1]);
    if (preg_match('{<li>Longitude : ([^<]*)</li>}i', $content, $regs)) $araResp['longitude'] = trim($regs[1]);
    if (preg_match('{<li>Timezone : ([^<]*)</li>}i', $content, $regs)) $araResp['timezone'] = trim($regs[1]);
    if (preg_match('{<li>Hostname : ([^<]*)</li>}i', $content, $regs)) $araResp['hostname'] = trim($regs[1]);

    $strResp = ($araResp['city'] != '' && $araResp['state'] != '') ? ($araResp['city'] . ', ' . $araResp['state']) : 'UNKNOWN';

    return $asArray ? $araResp : $strResp;
}

To Use

detect_location();
//  returns "CITY, STATE" based on user IP

detect_location('xxx.xxx.xxx.xxx');
//  returns "CITY, STATE" based on IP you provide

detect_location(NULL, TRUE);    //   based on user IP
//  returns array(8) { ["city"] => "CITY", ["state"] => "STATE", ["country"] => "US", ["zip"] => "xxxxx", ["latitude"] => "xx.xxxxxx", ["longitude"] => "-xx.xxxxxx", ["timezone"] => "-07:00", ["hostname"] => "xx-xx-xx-xx.host.name.net" }

detect_location('xxx.xxx.xxx.xxx', TRUE);   //   based on IP you provide
//  returns array(8) { ["city"] => "CITY", ["state"] => "STATE", ["country"] => "US", ["zip"] => "xxxxx", ["latitude"] => "xx.xxxxxx", ["longitude"] => "-xx.xxxxxx", ["timezone"] => "-07:00", ["hostname"] => "xx-xx-xx-xx.host.name.net" }
SpYk3HH
  • 22,272
  • 11
  • 70
  • 81
2

You can also use "smart-ip" service:

$.getJSON("http://smart-ip.net/geoip-json?callback=?",
    function (data) {
        alert(data.countryName);
        alert(data.city);
    }
);
Roman Pushkin
  • 5,639
  • 3
  • 40
  • 58
2

I've done a bunch of testing with IP address services and here are a few ways I do it myself. First off a bunch off links to useful websites that I use:

https://db-ip.com/db Has a free ip-lookup service and has a few free csv files you can download. This uses a free api key that is attached to your email. It limits at 2000 queries per day.

http://ipinfo.io/ Free ip-lookup service without a api-key PHP functions:

//uses http://ipinfo.io/.
function ip_visitor_country($ip){
    $ip_data_in = get_web_page("http://ipinfo.io/".$ip."/json"); //add the ip to the url and retrieve the json data
    $ip_data = json_decode($ip_data_in['content'],true); //json_decode it for php use

    //this ip-lookup service returns 404 if the ip is invalid/not found so return false if this is the case.
    if(empty($ip_data) || $ip_data_in['httpcode'] == 404){
        return false;
    }else{
        return $ip_data; 
    }
}

function get_web_page($url){
    $user_agent = 'Mozilla/5.0 (Windows NT 6.1; rv:8.0) Gecko/20100101 Firefox/8.0';

    $options = array(
        CURLOPT_CUSTOMREQUEST  =>"GET",        //set request type post or get
        CURLOPT_POST           =>false,        //set to GET
        CURLOPT_USERAGENT      => $user_agent, //set user agent
        CURLOPT_RETURNTRANSFER => true,     // return web page
        CURLOPT_HEADER         => false,    // don't return headers
        CURLOPT_FOLLOWLOCATION => true,     // follow redirects
        CURLOPT_ENCODING       => "",       // handle all encodings
        CURLOPT_AUTOREFERER    => true,     // set referer on redirect
        CURLOPT_CONNECTTIMEOUT => 120,      // timeout on connect
        CURLOPT_TIMEOUT        => 120,      // timeout on response
        CURLOPT_MAXREDIRS      => 10,       // stop after 10 redirects
    );
    $ch = curl_init( $url );
    curl_setopt_array( $ch, $options );
    $content = curl_exec( $ch );
    $err     = curl_errno( $ch );
    $errmsg  = curl_error( $ch );
    $header  = curl_getinfo( $ch );
    $httpCode = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
    curl_close( $ch );  
    $header['errno']   = $err; //curl error code
    $header['errmsg']  = $errmsg; //curl error message
    $header['content'] = $content; //the webpage result (In this case the ip data in json array form)
    $header['httpcode'] = $httpCode; //the webpage response code
    return $header; //return the collected data and response codes
}

In the end you get something like this:

Array
(
    [ip] => 1.1.1.1
    [hostname] => No Hostname
    [city] => 
    [country] => AU
    [loc] => -27.0000,133.0000
    [org] => AS15169 Google Inc.
)

http://www.geoplugin.com/ Slightly older but this service gives you a bunch of extra usefull information such as the currency off the country, continent code, longitude and more.


http://lite.ip2location.com/database-ip-country-region-city-latitude-longitude Offers a bunch of downloadable files with instructions to import them into your database. Once you have one off these files in your database you can select the data fairly easily.

SELECT * FROM `ip2location_db5` WHERE IP > ip_from AND IP < ip_to

Use the php function ip2long(); to turn the ip-address into a numeric value. For example 1.1.1.1 becomes 16843009. This lets you scan for the ip ranges given to you by the database file.

So in order to find out where 1.1.1.1 belongs to all we do is run this query:

SELECT * FROM `ip2location_db5` WHERE 16843009 > ip_from AND 16843009 < ip_to;

This returns this data as a example.

FROM: 16843008
TO: 16843263
Country code: AU
Country: Australia
Region: Queensland
City: Brisbane
Latitude: -27.46794
Longitude: 153.02809
Crecket
  • 718
  • 2
  • 7
  • 24
2

There 2 broad approaches to perform IP geolocation: one is to download a dataset, host it on your infrastructure and maintain it up-to-date. This requires time and effort, especially if you need to support a high number of requests. Another solution is to use an existing API service that manages all the work for you and more.

There exist many API Geolocation services: Maxmind, Ip2location, Ipstack, IpInfo, etc. Recently, the company I work for has switched to Ipregistry (https://ipregistry.co) and I was involved in the decision and implementation process. Here are some elements you should consider while looking for an IP geolocation API:

  • Is the service accurate? are they using a single source of information?
  • Can they really handle your load?
  • Do they provide consistent and fast response times Worldwide (except if your users are country specific)?
  • What's their pricing model?

Here is an example to get IP geolocation information (but also threat and user agent data using one call):

$ip = $_SERVER['REMOTE_ADDR'];
$details = json_decode(file_get_contents("https://api.ipregistry.co/{$ip}?key=tryout"));
echo $details->location;

Note: I am not here to promote Ipregistry and say it's the best but I spent a long time analyzing existing solutions and their solution is really promising.

BonieE
  • 31
  • 2