Getting the location from an IP address [closed]

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.

0

20 Answers

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, . They provide hostname, geolocation, network owner and additional information, eg:

$ curl { "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("")); echo $details->city; // -> "Mountain View" 

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

$.get("", function (response) { $("#ip").html("IP: " + response.ip); $("#address").html("Location: " + response.city + ", " + response.region); $("#details").html(JSON.stringify(response, null, 4)); }, "jsonp");
<script src=""></script> <h3>Client side IP geolocation using <a href="">ipinfo.io</a></h3> <hr/> <div></div> <div></div> <hr/>Full response: <pre></pre>
11

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('); 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": "" } 
7

A pure Javascript example, using the services of They provide a JSON and JSONP-callback solution.

  • JSON:
  • JSONP-callback:

No jQuery required!

<!DOCTYPE html> <html> <head> <title>Geo City Locator by geolocation-db.com</title> </head> <body> <div>Country: <span></span></div> <div>State: <span></span></div> <div>City: <span></span></div> <div>Postal: <span></span></div> <div>Latitude: <span></span></div> <div>Longitude: <span></span></div> <div>IP address: <span></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 = ' var h = document.getElementsByTagName('script')[0]; h.parentNode.insertBefore(script, h); </script> </html>
0

Using Google APIS:

<script type="text/javascript" src=""></script> <script> contry_code = google.loader.ClientLocation.address.country_code city = google.loader.ClientLocation.address.city region = google.loader.ClientLocation.address.region </script> 
4

You need to use an external service... such as 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.

4

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(' false, $context); 

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

echo file_get_contents(' false, $context); 
0

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.

0

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

$data = file_get_contents(""); //$data contains: "US" $data = file_get_contents(""); //$data contains: XML with country, lat, long, city, etc... 

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

0

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("")); 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 
1

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

<?php $res = file_get_contents('); $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.

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".

1

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.

1

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']; 
1

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("" . $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(' 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); } }); 

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("")); 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("", 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=""></script> <div></div> <div></div> <div></div> <pre></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.

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("" + $('#txtIP').val(), function (result) { alert('City Name: ' + result.city) console.log(result); }); }); }); 

Php Code:

$result = json_decode(file_get_contents(')); 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 } 
0

The following is a modified version of a snippet I found that uses 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 = ' . 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 => ' . $_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" } 

You can also use "smart-ip" service:

$.getJSON("", function (data) { alert(data.countryName); alert(data.city); } ); 

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:

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.

Free ip-lookup service without a api-key PHP functions:

//uses function ip_visitor_country($ip){ $ip_data_in = get_web_page("".$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. ) 

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.


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 
0

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 () 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("")); 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.

You Might Also Like