Get country code from IP address, Easy php ( Linux servers only )

Once upon a time, I was writing a system that needed to know where roughly a user / visitor was coming from.
I had a HUGE icon set for every country code ( from famfamfam.com ) so I needed a way to map a visitors IP to a country code using PHP.

I didn’t want to rely on any 3rd party servers ( some offer a simple get request and reply with info )
Most of the time these sites are wrong and charge to use it more than a few hundred times.

I was gonna do thousands a day, So needed to do this myself without buying a database with EVERY internet address in it.

So,
I came up with this:
– Visitor visits my site.
– PHP gets the users ip address.
– PHP does a whois and parses the data returned.
– PHP updates a database with the users IP address and country code.
+ Any other page then querys the DB for the IP and countrycode and then uses that CC to show the country code image.

Here is how i did it.
You will need a linux server and permissions to execute local system commands ( in this case, Use whois via the exec php command. )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
// PHP file.
// Created By: hauntednipple.co.uk
$ip = $_SERVER['REMOTE_ADDR'];
 
$country = exec("whois $ip  | grep -i country"); // Run a local whois and get the result back
$country = strtolower($country); // Make all text lower case so we can use str_replace happily
// Clean up the results as some whois results come back with odd results, this should cater for most issues
$country = str_replace("country:", "", "$country");
$country = str_replace("Country:", "", "$country");
$country = str_replace("Country :", "", "$country");
$country = str_replace("country :", "", "$country");
$country = str_replace("network:country-code:", "", "$country"); 
$country = str_replace("network:Country-Code:", "", "$country"); 
$country = str_replace("Network:Country-Code:", "", "$country");
$country = str_replace("network:organization-", "", "$country"); 
$country = str_replace("network:organization-usa", "us", "$country");
$country = str_replace("network:country-code;i:us", "us", "$country");
$country = str_replace("eu#countryisreallysomewhereinafricanregion", "af", "$country");
$country = str_replace("", "", "$country");
$country = str_replace("countryunderunadministration", "", "$country");
$country = str_replace(" ", "", "$country");
?>

Now, when you echo $country;
You will get the result of something like “fr” or “us” or “gb” etc. etc. etc.

If you have any ideas on how to improve this then please let me know.

It works fine for me and ive made a few changes where if $country == “” then $country = “unknown”
That way you can also mark unknown countrys ( doesnt come up that often )

Whois database querys may be limited if you get a LOT of hits from the same country / ISP, However for most uses it works fine and has served me well for a long time now.

Enjoy.