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