Getting visitors country from their IP

PhpGeolocationIpCountry Codes

Php Problem Overview


I want to get visitors country via their IP... Right now I'm using this (http://api.hostip.info/country.php?ip=...... )

Here is my code:

<?php

if (isset($_SERVER['HTTP_CLIENT_IP']))
{
    $real_ip_adress = $_SERVER['HTTP_CLIENT_IP'];
}

if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
{
    $real_ip_adress = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
else
{
    $real_ip_adress = $_SERVER['REMOTE_ADDR'];
}

$cip = $real_ip_adress;
$iptolocation = 'http://api.hostip.info/country.php?ip=' . $cip;
$creatorlocation = file_get_contents($iptolocation);

?>

Well, it's working properly, but the thing is, this returns the country code like US or CA., and not the whole country name like United States or Canada.

So, is there any good alternative to hostip.info offers this?

I know that I can just write some code that will eventually turn this two letters to whole country name, but I'm just too lazy to write a code that contains all countries...

P.S: For some reason I don't want to use any ready made CSV file or any code that will grab this information for me, something like ip2country ready made code and CSV.

Php Solutions


Solution 1 - Php

Try this simple PHP function.

<?php

function ip_info($ip = NULL, $purpose = "location", $deep_detect = TRUE) {
	$output = NULL;
	if (filter_var($ip, FILTER_VALIDATE_IP) === FALSE) {
		$ip = $_SERVER["REMOTE_ADDR"];
		if ($deep_detect) {
			if (filter_var(@$_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP))
				$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
			if (filter_var(@$_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP))
				$ip = $_SERVER['HTTP_CLIENT_IP'];
		}
	}
	$purpose    = str_replace(array("name", "\n", "\t", " ", "-", "_"), NULL, strtolower(trim($purpose)));
	$support    = array("country", "countrycode", "state", "region", "city", "location", "address");
	$continents = array(
		"AF" => "Africa",
		"AN" => "Antarctica",
		"AS" => "Asia",
		"EU" => "Europe",
		"OC" => "Australia (Oceania)",
		"NA" => "North America",
		"SA" => "South America"
	);
	if (filter_var($ip, FILTER_VALIDATE_IP) && in_array($purpose, $support)) {
		$ipdat = @json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip=" . $ip));
		if (@strlen(trim($ipdat->geoplugin_countryCode)) == 2) {
			switch ($purpose) {
				case "location":
					$output = array(
						"city"           => @$ipdat->geoplugin_city,
						"state"          => @$ipdat->geoplugin_regionName,
						"country"        => @$ipdat->geoplugin_countryName,
						"country_code"   => @$ipdat->geoplugin_countryCode,
						"continent"      => @$continents[strtoupper($ipdat->geoplugin_continentCode)],
						"continent_code" => @$ipdat->geoplugin_continentCode
					);
					break;
				case "address":
					$address = array($ipdat->geoplugin_countryName);
					if (@strlen($ipdat->geoplugin_regionName) >= 1)
						$address[] = $ipdat->geoplugin_regionName;
					if (@strlen($ipdat->geoplugin_city) >= 1)
						$address[] = $ipdat->geoplugin_city;
					$output = implode(", ", array_reverse($address));
					break;
				case "city":
					$output = @$ipdat->geoplugin_city;
					break;
				case "state":
					$output = @$ipdat->geoplugin_regionName;
					break;
				case "region":
					$output = @$ipdat->geoplugin_regionName;
					break;
				case "country":
					$output = @$ipdat->geoplugin_countryName;
					break;
				case "countrycode":
					$output = @$ipdat->geoplugin_countryCode;
					break;
			}
		}
	}
	return $output;
}

?>

How to use:

Example1: Get visitor IP address details

<?php

echo ip_info("Visitor", "Country"); // India
echo ip_info("Visitor", "Country Code"); // IN
echo ip_info("Visitor", "State"); // Andhra Pradesh
echo ip_info("Visitor", "City"); // Proddatur
echo ip_info("Visitor", "Address"); // Proddatur, Andhra Pradesh, India

print_r(ip_info("Visitor", "Location")); // Array ( [city] => Proddatur [state] => Andhra Pradesh [country] => India [country_code] => IN [continent] => Asia [continent_code] => AS )

?>

Example 2: Get details of any IP address. [Support IPV4 & IPV6]

<?php

echo ip_info("173.252.110.27", "Country"); // United States
echo ip_info("173.252.110.27", "Country Code"); // US
echo ip_info("173.252.110.27", "State"); // California
echo ip_info("173.252.110.27", "City"); // Menlo Park
echo ip_info("173.252.110.27", "Address"); // Menlo Park, California, United States

print_r(ip_info("173.252.110.27", "Location")); // Array ( [city] => Menlo Park [state] => California [country] => United States [country_code] => US [continent] => North America [continent_code] => NA )

?>

Solution 2 - Php

You can use a simple API from http://www.geoplugin.net/

$xml = simplexml_load_file("http://www.geoplugin.net/xml.gp?ip=".getRealIpAddr());
echo $xml->geoplugin_countryName ;


echo "<pre>";
foreach ($xml as $key => $value)
{
	echo $key , "= " , $value ,  " \n" ;
}
echo "</pre>";

Function Used

function getRealIpAddr()
{
    if (!empty($_SERVER['HTTP_CLIENT_IP']))   //check ip from share internet
    {
      $ip=$_SERVER['HTTP_CLIENT_IP'];
    }
    elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))   //to check ip is pass from proxy
    {
      $ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
    }
    else
    {
      $ip=$_SERVER['REMOTE_ADDR'];
    }
    return $ip;
}

Output

United States
geoplugin_city= San Antonio
geoplugin_region= TX
geoplugin_areaCode= 210
geoplugin_dmaCode= 641
geoplugin_countryCode= US
geoplugin_countryName= United States
geoplugin_continentCode= NA
geoplugin_latitude= 29.488899230957
geoplugin_longitude= -98.398696899414
geoplugin_regionCode= TX
geoplugin_regionName= Texas
geoplugin_currencyCode= USD
geoplugin_currencySymbol= $
geoplugin_currencyConverter= 1

It makes you have so many options you can play around with

Thanks

:)

Solution 3 - Php

I tried Chandra's answer but my server configuration does not allow file_get_contents()

PHP Warning: file_get_contents() URL file-access is disabled in the server configuration

I modified Chandra's code so that it also works for servers like that using cURL:

function ip_visitor_country()
{

	$client  = @$_SERVER['HTTP_CLIENT_IP'];
	$forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
	$remote  = $_SERVER['REMOTE_ADDR'];
	$country  = "Unknown";
	
	if(filter_var($client, FILTER_VALIDATE_IP))
	{
		$ip = $client;
	}
	elseif(filter_var($forward, FILTER_VALIDATE_IP))
	{
		$ip = $forward;
	}
	else
	{
		$ip = $remote;
	}
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, "http://www.geoplugin.net/json.gp?ip=".$ip);
	curl_setopt($ch, CURLOPT_HEADER, 0);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
	$ip_data_in = curl_exec($ch); // string
	curl_close($ch);

	$ip_data = json_decode($ip_data_in,true);
	$ip_data = str_replace('&quot;', '"', $ip_data); // for PHP 5.2 see stackoverflow.com/questions/3110487/
	
	if($ip_data && $ip_data['geoplugin_countryName'] != null) {
		$country = $ip_data['geoplugin_countryName'];
	}
 
	return 'IP: '.$ip.' # Country: '.$country;
}

echo ip_visitor_country(); // output Coutry name

?>

Hope that helps ;-)

Solution 4 - Php

Use MaxMind GeoIP (or GeoIPLite if you are not ready to pay).

$gi = geoip_open('GeoIP.dat', GEOIP_MEMORY_CACHE);
$country = geoip_country_code_by_addr($gi, $_SERVER['REMOTE_ADDR']);
geoip_close($gi);

Solution 5 - Php

You can use a web-service from http://ip-api.com<br /> in your php code, do as follow :

<?php
$ip = $_REQUEST['REMOTE_ADDR']; // the IP address to query
$query = @unserialize(file_get_contents('http://ip-api.com/php/'.$ip));
if($query && $query['status'] == 'success') {
  echo 'Hello visitor from '.$query['country'].', '.$query['city'].'!';
} else {
  echo 'Unable to get location';
}
?>

the query have many other informations:

array (
  'status'      => 'success',
  'country'     => 'COUNTRY',
  'countryCode' => 'COUNTRY CODE',
  'region'      => 'REGION CODE',
  'regionName'  => 'REGION NAME',
  'city'        => 'CITY',
  'zip'         => ZIP CODE,
  'lat'         => LATITUDE,
  'lon'         => LONGITUDE,
  'timezone'    => 'TIME ZONE',
  'isp'         => 'ISP NAME',
  'org'         => 'ORGANIZATION NAME',
  'as'          => 'AS NUMBER / NAME',
  'query'       => 'IP ADDRESS USED FOR QUERY',
)

Solution 6 - Php

Actually, you can call http://api.hostip.info/?ip=123.125.114.144 to get the information, which is presented in XML.

Solution 7 - Php

Check out php-ip-2-country from code.google. The database they provide is updated daily, so it is not necessary to connect to an outside server for the check if you host your own SQL server. So using the code you would only have to type:

<?php
$ip = $_SERVER['REMOTE_ADDR'];

if(!empty($ip)){
        require('./phpip2country.class.php');
       
        /**
         * Newest data (SQL) avaliable on project website
         * @link http://code.google.com/p/php-ip-2-country/
         */
        $dbConfigArray = array(
                'host' => 'localhost', //example host name
                'port' => 3306, //3306 -default mysql port number
                'dbName' => 'ip_to_country', //example db name
                'dbUserName' => 'ip_to_country', //example user name
                'dbUserPassword' => 'QrDB9Y8CKMdLDH8Q', //example user password
                'tableName' => 'ip_to_country', //example table name
        );
       
        $phpIp2Country = new phpIp2Country($ip,$dbConfigArray);
        $country = $phpIp2Country->getInfo(IP_COUNTRY_NAME);
        echo $country;
?>

Example Code (from the resource)

<?
require('phpip2country.class.php');
        
$dbConfigArray = array(
        'host' => 'localhost', //example host name
        'port' => 3306, //3306 -default mysql port number
        'dbName' => 'ip_to_country', //example db name
        'dbUserName' => 'ip_to_country', //example user name
        'dbUserPassword' => 'QrDB9Y8CKMdLDH8Q', //example user password
        'tableName' => 'ip_to_country', //example table name
);
        
$phpIp2Country = new phpIp2Country('213.180.138.148',$dbConfigArray);
        
print_r($phpIp2Country->getInfo(IP_INFO));
?>

Output

Array
(
    [IP_FROM] => 3585376256
    [IP_TO] => 3585384447
    [REGISTRY] => RIPE
    [ASSIGNED] => 948758400
    [CTRY] => PL
    [CNTRY] => POL
    [COUNTRY] => POLAND
    [IP_STR] => 213.180.138.148
    [IP_VALUE] => 3585378964
    [IP_FROM_STR] => 127.255.255.255
    [IP_TO_STR] => 127.255.255.255
)

Solution 8 - Php

Use following services

  1. http://api.hostip.info/get_html.php?ip=12.215.42.19

$json = file_get_contents('http://freegeoip.appspot.com/json/66.102.13.106');
$expression = json_decode($json);
print_r($expression);

3) http://ipinfodb.com/ip_location_api.php

Solution 9 - Php

We can use geobytes.com to get the location using user IP address

$user_ip = getIP();
$meta_tags = get_meta_tags('http://www.geobytes.com/IPLocator.htm?GetLocation&template=php3.txt&IPAddress=' . $user_ip);
echo '<pre>';
print_r($meta_tags);

it will return data like this

Array(
    [known] => true
    [locationcode] => USCALANG
    [fips104] => US
    [iso2] => US
    [iso3] => USA
    [ison] => 840
    [internet] => US
    [countryid] => 254
    [country] => United States
    [regionid] => 126
    [region] => California
    [regioncode] => CA
    [adm1code] =>     
    [cityid] => 7275
    [city] => Los Angeles
    [latitude] => 34.0452
    [longitude] => -118.2840
    [timezone] => -08:00
    [certainty] => 53
    [mapbytesremaining] => Free
)

Function to get user IP

function getIP(){
if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])){
    $pattern = "/^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/";
    if(preg_match($pattern, $_SERVER["HTTP_X_FORWARDED_FOR"])){
            $userIP = $_SERVER["HTTP_X_FORWARDED_FOR"];
    }else{
            $userIP = $_SERVER["REMOTE_ADDR"];
    }
}
else{
  $userIP = $_SERVER["REMOTE_ADDR"];
}
return $userIP;
}

Solution 10 - Php

Try this simple one line code, You will get country and city of visitors from their ip remote address.

$tags = get_meta_tags('http://www.geobytes.com/IpLocator.htm?GetLocation&template=php3.txt&IpAddress=' . $_SERVER['REMOTE_ADDR']);
echo $tags['country'];
echo $tags['city'];

Solution 11 - Php

There is a well-maintained flat-file version of the ip->country database maintained by the Perl community at CPAN

Access to those files does not require a dataserver, and the data itself is roughly 515k

Higemaru has written a PHP wrapper to talk to that data: php-ip-country-fast

Solution 12 - Php

Many different ways to do it...

#Solution #1:

One third party service you could use is http://ipinfodb.com. They provide hostname, geolocation and additional information.

Register for an API key here: http://ipinfodb.com/register.php. This will allow you to retrieve results from their server, without this it will not work.

Copy and past the following PHP code:

$ipaddress = $_SERVER['REMOTE_ADDR'];
$api_key = 'YOUR_API_KEY_HERE';

$data = file_get_contents("http://api.ipinfodb.com/v3/ip-city/?key=$api_key&ip=$ipaddress&format=json");
$data = json_decode($data);
$country = $data['Country'];

Downside:

Quoting from their website:

> Our free API is using IP2Location Lite version which provides lower > accuracy.

#Solution #2:

This function will return country name using the http://www.netip.de/ service.

$ipaddress = $_SERVER['REMOTE_ADDR'];
function geoCheckIP($ip)
{
    $response=@file_get_contents('http://www.netip.de/search?query='.$ip);

    $patterns=array();
    $patterns["country"] = '#Country: (.*?)&nbsp;#i';

    $ipInfo=array();

    foreach ($patterns as $key => $pattern)
    {
        $ipInfo[$key] = preg_match($pattern,$response,$value) && !empty($value[1]) ? $value[1] : 'not found';
    }

        return $ipInfo;
}

print_r(geoCheckIP($ipaddress));

Output:

Array ( [country] => DE - Germany )  // Full Country Name

Solution 13 - Php

My service ipdata.co provides the country name in 5 languages! As well as the organisation, currency, timezone, calling code, flag, Mobile Carrier data, Proxy data and Tor Exit Node status data from any IPv4 or IPv6 address.

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

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

The options include; English (en), German (de), Japanese (ja), French (fr) and Simplified Chinese (za-CH)

$ip = '74.125.230.195';
$details = json_decode(file_get_contents("https://api.ipdata.co/{$ip}?api-key=test"));
echo $details->country_name;
//United States
echo $details->city;
//Mountain View
$details = json_decode(file_get_contents("https://api.ipdata.co/{$ip}?api-key=test/zh-CN"));
echo $details->country_name;
//美国

Solution 14 - Php

Not sure if this is a new service but now (2016) the easiest way in php is to use geoplugin's php web service: http://www.geoplugin.net/php.gp:

Basic usage:

// GET IP ADDRESS
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
	$ip = $_SERVER['HTTP_CLIENT_IP'];
} else if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
	$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else if (!empty($_SERVER['REMOTE_ADDR'])) {
	$ip = $_SERVER['REMOTE_ADDR'];
} else {
    $ip = false;
}

// CALL THE WEBSERVICE
$ip_info = unserialize(file_get_contents('http://www.geoplugin.net/php.gp?ip='.$ip));

They also provide a ready built class: http://www.geoplugin.com/_media/webservices/geoplugin.class.php.tgz?id=webservices%3Aphp&cache=cache

Solution 15 - Php

Would that be acceptable ? pure PHP

$country = geoip_country_code_by_name($_SERVER['REMOTE_ADDR']);
print $country;

ref: https://www.php.net/manual/en/function.geoip-country-code-by-name.php

Solution 16 - Php

you can use http://ipinfo.io/ to get details of ip address Its easy to use .

<?php
    function ip_details($ip)
    {
    $json = file_get_contents("http://ipinfo.io/{$ip}");
    $details = json_decode($json);
    return $details;
    }
     
    $details = ip_details(YoUR IP ADDRESS); 
     
    echo $details->city;
    echo "<br>".$details->country; 
    echo "<br>".$details->org; 
    echo "<br>".$details->hostname; /
     
    ?>

Solution 17 - Php

A one liner with an IP address to country API

echo file_get_contents('https://ipapi.co/8.8.8.8/country_name/');

> United States

Example :

https://ipapi.co/country_name/ - your country

https://ipapi.co/8.8.8.8/country_name/ - country for IP 8.8.8.8

Solution 18 - Php

I am using ipinfodb.com api and getting exactly what you are looking for.

Its completely free, you just need to register with them to get your api key. You can include their php class by downloading from their website or you can use url format to retrieve information.

Here's what I am doing:

I included their php class in my script and using the below code:

$ipLite = new ip2location_lite;
$ipLite->setKey('your_api_key');
if(!$_COOKIE["visitorCity"]){ //I am using cookie to store information
  $visitorCity = $ipLite->getCity($_SERVER['REMOTE_ADDR']);
  if ($visitorCity['statusCode'] == 'OK') {
    $data = base64_encode(serialize($visitorCity));
    setcookie("visitorCity", $data, time()+3600*24*7); //set cookie for 1 week
  }
}
$visitorCity = unserialize(base64_decode($_COOKIE["visitorCity"]));
echo $visitorCity['countryName'].' Region'.$visitorCity['regionName'];

Thats it.

Solution 19 - Php

Replace 127.0.0.1 with visitors IpAddress.

$country = geoip_country_name_by_name('127.0.0.1');

Installation instructions are here, and read this to know how to obtain City, State, Country, Longitude, Latitude, etc...

Solution 20 - Php

I have a short answer which I have used in a project. In my answer, I consider that you have visitor IP address.

$ip = "202.142.178.220";
$ipdat = @json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip=" . $ip));
//get ISO2 country code
if(property_exists($ipdat, 'geoplugin_countryCode')) {
    echo $ipdat->geoplugin_countryCode;
}
//get country full name
if(property_exists($ipdat, 'geoplugin_countryName')) {
    echo $ipdat->geoplugin_countryName;
}

Solution 21 - Php

I know this is old, but I tried a few other solutions on here and they seem to be outdated or just return null. So this is how I did it.

Using http://www.geoplugin.net/json.gp?ip= which doesn't require any type of sign up or paying for the service.

function get_client_ip_server() {
  $ipaddress = '';
if (isset($_SERVER['HTTP_CLIENT_IP']))
  $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
else if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
  $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
else if(isset($_SERVER['HTTP_X_FORWARDED']))
  $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
else if(isset($_SERVER['HTTP_FORWARDED_FOR']))
  $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
else if(isset($_SERVER['HTTP_FORWARDED']))
  $ipaddress = $_SERVER['HTTP_FORWARDED'];
else if(isset($_SERVER['REMOTE_ADDR']))
  $ipaddress = $_SERVER['REMOTE_ADDR'];
else
  $ipaddress = 'UNKNOWN';

  return $ipaddress;
}

$ipaddress = get_client_ip_server();

function getCountry($ip){
    $curlSession = curl_init();
    curl_setopt($curlSession, CURLOPT_URL, 'http://www.geoplugin.net/json.gp?ip='.$ip);
    curl_setopt($curlSession, CURLOPT_BINARYTRANSFER, true);
    curl_setopt($curlSession, CURLOPT_RETURNTRANSFER, true);

    $jsonData = json_decode(curl_exec($curlSession));
    curl_close($curlSession);

    return $jsonData->geoplugin_countryCode;
}

echo "County: " .getCountry($ipaddress);

And if you want extra information about it, this is a full return of Json:

{
  "geoplugin_request":"IP_ADDRESS",
  "geoplugin_status":200,
  "geoplugin_delay":"2ms",
  "geoplugin_credit":"Some of the returned data includes GeoLite data created by MaxMind, available from <a href='http:\/\/www.maxmind.com'>http:\/\/www.maxmind.com<\/a>.",
  "geoplugin_city":"Current City",
  "geoplugin_region":"Region",
  "geoplugin_regionCode":"Region Code",
  "geoplugin_regionName":"Region Name",
  "geoplugin_areaCode":"",
  "geoplugin_dmaCode":"650",
  "geoplugin_countryCode":"US",
  "geoplugin_countryName":"United States",
  "geoplugin_inEU":0,
  "geoplugin_euVATrate":false,
  "geoplugin_continentCode":"NA",
  "geoplugin_continentName":"North America",
  "geoplugin_latitude":"37.5563",
  "geoplugin_longitude":"-99.9413",
  "geoplugin_locationAccuracyRadius":"5",
  "geoplugin_timezone":"America\/Chicago",
  "geoplugin_currencyCode":"USD",
  "geoplugin_currencySymbol":"$",
  "geoplugin_currencySymbol_UTF8":"$",
  "geoplugin_currencyConverter":1
}

Solution 22 - Php

I have written a class based on "Chandra Nakka" answer. Hopefully it can help people out it saves the information from geoplugin to a session so the load is much faster when recalling the information. It also saves the values to a private array so recalling in the same code is the fastest as it could be.

class Geo {
private $_ip = null;
private $_useSession = true;
private $_sessionNameData = 'GEO_SESSION_DATA';
private $_hasError = false;
private $_geoData = [];

const PURPOSE_SUPPORT = [
	"all", "*", "location",
	"request",
	"latitude", 
	"longitude",
	"accuracy",
	"timezonde",
	"currencycode",
	"currencysymbol",
	"currencysymbolutf8",
	"country", 
	"countrycode", 
	"state", "region", 
	"city", 
	"address",
	"continent", 
	"continentcode"
];
const CONTINENTS = [
	"AF" => "Africa",
	"AN" => "Antarctica",
	"AS" => "Asia",
	"EU" => "Europe",
	"OC" => "Australia (Oceania)",
	"NA" => "North America",
	"SA" => "South America"
];

function __construct($ip = null, $deepDetect = true, $useSession = true)
{
	// define the session useage within this class
	$this->_useSession = $useSession;
	$this->_startSession();
	
	// define a ip as far as possible
	$this->_ip = $this->_defineIP($ip, $deepDetect);

	// check if the ip was set
	if (!$this->_ip) {
		$this->_hasError = true;
		return $this;
	}
	
	// define the geoData
	$this->_geoData = $this->_fetchGeoData();
	
	return $this;
}

function get($purpose)
{
	// making sure its lowercase
	$purpose = strtolower($purpose);
	
	// makeing sure there are no error and the geodata is not empty
	if ($this->_hasError || !count($this->_geoData) && !in_array($purpose, self::PURPOSE_SUPPORT)) {
		return 'error';
	}
	
	if (in_array($purpose, ['*', 'all', 'location']))  {
		return $this->_geoData;
	}
	
	if ($purpose === 'state') $purpose = 'region';
	
	return (isset($this->_geoData[$purpose]) ? $this->_geoData[$purpose] : 'missing: '.$purpose);
}

private function _fetchGeoData()
{
	// check if geo data was set before
	if (count($this->_geoData)) {
		return $this->_geoData;
	}
	
	// check possible session
	if ($this->_useSession && ($sessionData = $this->_getSession($this->_sessionNameData))) {
		return $sessionData;
	}
	
	// making sure we have a valid ip
	if (!$this->_ip || $this->_ip === '127.0.0.1') {
		return [];
	}
	
	// fetch the information from geoplusing
	$ipdata = @json_decode($this->curl("http://www.geoplugin.net/json.gp?ip=" . $this->_ip));
	
	// check if the data was fetched
	if (!@strlen(trim($ipdata->geoplugin_countryCode)) === 2) {
		return [];
	}
	
	// make a address array
	$address = [$ipdata->geoplugin_countryName];
	if (@strlen($ipdata->geoplugin_regionName) >= 1)
		$address[] = $ipdata->geoplugin_regionName;
	if (@strlen($ipdata->geoplugin_city) >= 1)
		$address[] = $ipdata->geoplugin_city;
	
	// makeing sure the continentCode is upper case
	$continentCode = strtoupper(@$ipdata->geoplugin_continentCode);
	
	$geoData = [
		'request' => @$ipdata->geoplugin_request,
		'latitude' => @$ipdata->geoplugin_latitude,
		'longitude' => @$ipdata->geoplugin_longitude,
		'accuracy' => @$ipdata->geoplugin_locationAccuracyRadius,
		'timezonde' => @$ipdata->geoplugin_timezone,
		'currencycode' => @$ipdata->geoplugin_currencyCode,
		'currencysymbol' => @$ipdata->geoplugin_currencySymbol,
		'currencysymbolutf8' => @$ipdata->geoplugin_currencySymbol_UTF8,
		'city' => @$ipdata->geoplugin_city,
		'region' => @$ipdata->geoplugin_regionName,
		'country' => @$ipdata->geoplugin_countryName,
		'countrycode' => @$ipdata->geoplugin_countryCode,
		'continent' => self::CONTINENTS[$continentCode],
		'continentcode' => $continentCode,
		'address' => implode(", ", array_reverse($address))
	];
	
	if ($this->_useSession) {
		$this->_setSession($this->_sessionNameData, $geoData);
	}
	
	return $geoData;
}

private function _startSession()
{
	// only start a new session when the status is 'none' and the class
	// requires a session
	if ($this->_useSession && session_status() === PHP_SESSION_NONE) {
		session_start();
	}
}

private function _defineIP($ip, $deepDetect)
{
	// check if the ip was set before
	if ($this->_ip) {
		return $this->_ip;
	}
	
	// check if the ip given is valid
	if (filter_var($ip, FILTER_VALIDATE_IP)) {
		return $ip;
	}
	
	// try to get the ip from the REMOTE_ADDR
	$ip = filter_input(INPUT_SERVER, 'REMOTE_ADDR', FILTER_VALIDATE_IP);
	
	// check if we need to end the search for a IP if the REMOTE_ADDR did not
	// return a valid and the deepDetect is false
	if (!$deepDetect) {
		return $ip;
	}
	
	// try to get the ip from HTTP_X_FORWARDED_FOR
	if (($ip = filter_input(INPUT_SERVER, 'HTTP_X_FORWARDED_FOR', FILTER_VALIDATE_IP))) {
		return $ip;
	}

	// try to get the ip from the HTTP_CLIENT_IP
	if (($ip = filter_input(INPUT_SERVER, 'HTTP_CLIENT_IP', FILTER_VALIDATE_IP))) {
		return $ip;
	}
	
	return $ip;
}

private function _hasSession($key, $filter = FILTER_DEFAULT) 
{
	return (isset($_SESSION[$key]) ? (bool)filter_var($_SESSION[$key], $filter) : false);
}

private function _getSession($key, $filter = FILTER_DEFAULT)
{
	if ($this->_hasSession($key, $filter)) {
		$value = filter_var($_SESSION[$key], $filter);
		
		if (@json_decode($value)) {
			return json_decode($value, true);
		}
		
		return filter_var($_SESSION[$key], $filter);
	} else {
		return false;
	}
}

private function _setSession($key, $value) 
{
	if (is_array($value)) {
		$value = json_encode($value);
	}
	
	$_SESSION[$key] = $value;
}

function emptySession($key) {
	if (!$this->_hasSession($key)) {
		return;
	}
	
	$_SESSION[$key] = null;
	unset($_SESSION[$key]);
	
}

function curl($url) 
{
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_HEADER, 0);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	$output = curl_exec($ch);
	curl_close($ch);
	return $output;
}
}

Answering the 'op' question with this class you can call

$country = (new \Geo())->get('country'); // United Kingdom

And the other properties available are:

$geo = new \Geo('185.35.50.4');
var_dump($geo->get('*')); // allias all / location
var_dump($geo->get('country'));
var_dump($geo->get('countrycode'));
var_dump($geo->get('state')); // allias region
var_dump($geo->get('city')); 
var_dump($geo->get('address')); 
var_dump($geo->get('continent')); 
var_dump($geo->get('continentcode'));	
var_dump($geo->get('request'));
var_dump($geo->get('latitude'));
var_dump($geo->get('longitude'));
var_dump($geo->get('accuracy'));
var_dump($geo->get('timezonde'));
var_dump($geo->get('currencyCode'));
var_dump($geo->get('currencySymbol'));
var_dump($geo->get('currencySymbolUTF8'));

Returning

array(15) {
  ["request"]=>
  string(11) "185.35.50.4"
  ["latitude"]=>
  string(7) "51.4439"
  ["longitude"]=>
  string(7) "-0.1854"
  ["accuracy"]=>
  string(2) "50"
  ["timezonde"]=>
  string(13) "Europe/London"
  ["currencycode"]=>
  string(3) "GBP"
  ["currencysymbol"]=>
  string(2) "£"
  ["currencysymbolutf8"]=>
  string(2) "£"
  ["city"]=>
  string(10) "Wandsworth"
  ["region"]=>
  string(10) "Wandsworth"
  ["country"]=>
  string(14) "United Kingdom"
  ["countrycode"]=>
  string(2) "GB"
  ["continent"]=>
  string(6) "Europe"
  ["continentcode"]=>
  string(2) "EU"
  ["address"]=>
  string(38) "Wandsworth, Wandsworth, United Kingdom"
}
string(14) "United Kingdom"
string(2) "GB"
string(10) "Wandsworth"
string(10) "Wandsworth"
string(38) "Wandsworth, Wandsworth, United Kingdom"
string(6) "Europe"
string(2) "EU"
string(11) "185.35.50.4"
string(7) "51.4439"
string(7) "-0.1854"
string(2) "50"
string(13) "Europe/London"
string(3) "GBP"
string(2) "£"
string(2) "£"

Solution 23 - Php

The User Country API has exactly what you need. Here is a sample code using file_get_contents() as you originally do:

$result = json_decode(file_get_contents('http://usercountry.com/v1.0/json/'.$cip), true);
$result['country']['name']; // this contains what you need

Solution 24 - Php

You can get visitors country and city using ipstack geo API.You need to get your own ipstack API and then use the code below:

<?php
 $ip = $_SERVER['REMOTE_ADDR']; 
 $api_key = "YOUR_API_KEY";
 $freegeoipjson = file_get_contents("http://api.ipstack.com/".$ip."?access_key=".$api_key."");
 $jsondata = json_decode($freegeoipjson);
 $countryfromip = $jsondata->country_name;
 echo "Country: ". $countryfromip ."";
?>

Source: Get visitors country and city in PHP using ipstack API

Solution 25 - Php

This is just a security note on the functionality of get_client_ip() that most of the answers here have been included inside the main function of get_geo_info_for_this_ip().

Don't rely too much on the IP data in the request headers like Client-IP or X-Forwarded-For because they can be spoofed very easily, however you should rely on the source IP of the TCP connection that is actually established between our server and the client $_SERVER['REMOTE_ADDR'] as it can't be spoofed

$_SERVER['HTTP_CLIENT_IP'] // can be spoofed 
$_SERVER['HTTP_X_FORWARDED_FOR'] // can be spoofed 
$_SERVER['REMOTE_ADDR']// can't be spoofed 

It's OK to get the country of the spoofed IP but Keep in mind that using this IP in any security model (e.g: banning the IP that sends frequent requests) will destroy the entire security model. IMHO I prefer to use the actual client IP even if it is the IP of the proxy server.

Solution 26 - Php

Try

  <?php
  //gives you the IP address of the visitors
  if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
      $ip = $_SERVER['HTTP_CLIENT_IP'];}
  else if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
      $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
  } else {
      $ip = $_SERVER['REMOTE_ADDR'];
  }
  
  //return the country code
  $url = "http://api.wipmania.com/$ip";
  $country = file_get_contents($url);
  echo $country;

  ?>

Solution 27 - Php

You could use my service: https://SmartIP.io , which provides full country names and city names of any IP address. We also expose timezones, currency, proxy detection, TOR nodes detection and Crypto detection.

You just need to signup and get a free API key which allows for 250,000 requests per month.

Using the official PHP library, the API call becomes:

$apiKey = "your API key";
$smartIp = new SmartIP($apiKey);
$response = $smartIp->requestIPData("8.8.8.8");

echo "\nstatus code: " . $response->{"status-code"};
echo "\ncountry name: " . $response->country->{"country-name"};

Check the API documentation for more info: https://smartip.io/docs

Solution 28 - Php

As of 2019, MaxMind country DB can be used as follows:

<?php
require_once 'vendor/autoload.php';
use MaxMind\Db\Reader;
$databaseFile = 'GeoIP2-Country.mmdb';
$reader = new Reader($databaseFile);
$cc = $reader->get($_SERVER['REMOTE_ADDR'])['country']['iso_code'] # US/GB...
$reader->close();

Source: https://github.com/maxmind/MaxMind-DB-Reader-php

Solution 29 - Php

PHP code to obtain country, city,
continent, etc using IP Address

    $ip = $_SERVER["REMOTE_ADDR"];
      
    // Use JSON encoded string and converts 
    // it into a PHP variable 
    $ipdat = @json_decode(file_get_contents( 
        "http://www.geoplugin.net/json.gp?ip=" . $ip)); 
       
    $country = $ipdat->geoplugin_countryName; 
    $city = $ipdat->geoplugin_city; 
    $continent_name = $ipdat->geoplugin_continentName; 
    $latitude = $ipdat->geoplugin_latitude; 
    $longitude = $ipdat->geoplugin_longitude; 
    $currency_symbol = $ipdat->geoplugin_currencySymbol; 
    $currency_code = $ipdat->geoplugin_currencyCode; 
    $timezone = $ipdat->geoplugin_timezone; 

Solution 30 - Php

Here's the cleaner and working version of the accepted answer using guzzle:

You can use curl instead of guzzle it's just a simple get request.

    function ip_info($ip = NULL, $purpose = "location", $deep_detect = TRUE) {
        $output = NULL;
        if (filter_var($ip, FILTER_VALIDATE_IP) === FALSE) {
            $ip = $_SERVER["REMOTE_ADDR"];
            if ($deep_detect) {
                if (filter_var(@$_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP))
                    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
                if (filter_var(@$_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP))
                    $ip = $_SERVER['HTTP_CLIENT_IP'];
            }
        }
        $purpose    = str_replace(array("name", "\n", "\t", " ", "-", "_"), NULL, strtolower(trim($purpose)));
        $support    = array("country", "countrycode", "state", "region", "city", "location", "address");
        $continents = array(
            "AF" => "Africa",
            "AN" => "Antarctica",
            "AS" => "Asia",
            "EU" => "Europe",
            "OC" => "Australia (Oceania)",
            "NA" => "North America",
            "SA" => "South America"
        );
        if (filter_var($ip, FILTER_VALIDATE_IP) && in_array($purpose, $support, true)) {
            $client = New \GuzzleHttp\Client();
            $ipdat = json_decode($client->request('GET','http://www.geoplugin.net/json.gp',$params = [
                'query' => [
                    'ip' => $ip,
                ]
            ])->getBody()->getContents(),true);
            if (strlen(trim($ipdat['geoplugin_countryCode'])) === 2) {
                switch ($purpose) {
                    case "location":
                        $output = array(
                            "city"           => $ipdat['geoplugin_city'],
                            "state"          => $ipdat['geoplugin_regionName'],
                            "country"        => $ipdat['geoplugin_countryName'],
                            "country_code"   => $ipdat['geoplugin_countryCode'],
                            "continent"      => $continents[strtoupper($ipdat['geoplugin_continentCode'])],
                            "continent_code" => $ipdat['geoplugin_continentCode']
                        );
                        break;
                    case "address":
                        $address = array($ipdat['geoplugin_countryName']);
                        if (@strlen($ipdat['geoplugin_regionName']) >= 1)
                            $address[] = $ipdat['geoplugin_regionName'];
                        if (@strlen($ipdat['geoplugin_city']) >= 1)
                            $address[] = $ipdat['geoplugin_city'];
                        $output = implode(", ", array_reverse($address));
                        break;
                    case "city":
                        $output = $ipdat['geoplugin_city'];
                        break;
                    case "region":
                    case "state":
                        $output = $ipdat['geoplugin_regionName'];
                        break;
                    case "country":
                        $output = $ipdat['geoplugin_countryName'];
                        break;
                    case "countrycode":
                        $output = $ipdat['geoplugin_countryCode'];
                        break;
                }
            }
        }
        return $output;
    }

Solution 31 - Php

If you need to get country as fast as possible I would suggest geoip plugin for your web server.

For nginx here;

After you set this up properly, you will get countrycode from $_SERVER variable.

I execute this about 500(+-) times per seccond, super fast.

Solution 32 - Php

Achieve this with just 4 lines of code!

$user_ip = '0.0.0.0';
$user_ip = $_SERVER['REMOTE_ADDR'];
$close_url = stream_context_create(array('http' => array('header'=>'Connection: close\r\n')));
$user_country = json_decode(file_get_contents("https://ipinfo.io/$user_ip/json",false,$close_url));
echo "Yes! we ship to your country: <b>" . $user_country->country . "</b>";

//Output Yes! we ship to your country US

Note: $close_url is used to end the file_get_contents asap after content has been retrieved, it improves the speed of the request x5.

If you want to show the full country name you can click below and see how.

enter link description here

//echo "Peace to the world";

Solution 33 - Php

You can use this code snippest.

 if($a = unserialize(file_get_contents('http://www.geoplugin.net/php.gp?ip='.$_SERVER['REMOTE_ADDR']))){
        $countrycode= $a['geoplugin_countryCode'];
        if ($countrycode=='UK' ){
            header( 'Location: https://www.example.co.uk/' ) ;exit;
        }
    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlex C.View Question on Stackoverflow
Solution 1 - PhpChandra NakkaView Answer on Stackoverflow
Solution 2 - PhpBabaView Answer on Stackoverflow
Solution 3 - PhpAvatarView Answer on Stackoverflow
Solution 4 - PhpJoyce BabuView Answer on Stackoverflow
Solution 5 - PhpHalayem AnisView Answer on Stackoverflow
Solution 6 - PhpMarcusView Answer on Stackoverflow
Solution 7 - PhpAbsoluteƵERØView Answer on Stackoverflow
Solution 8 - PhpGBDView Answer on Stackoverflow
Solution 9 - PhpRam SharmaView Answer on Stackoverflow
Solution 10 - PhpSankar JayView Answer on Stackoverflow
Solution 11 - PhpdjsadinoffView Answer on Stackoverflow
Solution 12 - PhpimbondbabyView Answer on Stackoverflow
Solution 13 - PhpJonathanView Answer on Stackoverflow
Solution 14 - PhpEaten by a GrueView Answer on Stackoverflow
Solution 15 - Phppc_View Answer on Stackoverflow
Solution 16 - PhpAqib1604View Answer on Stackoverflow
Solution 17 - Phpuser6885709View Answer on Stackoverflow
Solution 18 - PhpMirajView Answer on Stackoverflow
Solution 19 - PhpJack M.View Answer on Stackoverflow
Solution 20 - PhpShahbazView Answer on Stackoverflow
Solution 21 - PhpJayceView Answer on Stackoverflow
Solution 22 - PhproyalwebsView Answer on Stackoverflow
Solution 23 - Phpbyl83View Answer on Stackoverflow
Solution 24 - PhpFaruque Ahamed MollickView Answer on Stackoverflow
Solution 25 - PhpAccountant مView Answer on Stackoverflow
Solution 26 - PhpDipanshu MahlaView Answer on Stackoverflow
Solution 27 - PhpkevinjView Answer on Stackoverflow
Solution 28 - PhpPedro LobitoView Answer on Stackoverflow
Solution 29 - PhpArsalan AhmedView Answer on Stackoverflow
Solution 30 - PhpSteve MoretzView Answer on Stackoverflow
Solution 31 - PhptemoView Answer on Stackoverflow
Solution 32 - PhpDexterView Answer on Stackoverflow
Solution 33 - PhpSanaullah AhmadView Answer on Stackoverflow