How can I determine a user's current location based on IP address (I guess it works this way).
-
You may want to take a look at [GeoIP Country Whois Locator](http://www.phpclasses.org/package/3582-PHP-Determine-the-country-of-an-IP-address-using-GeoIP.html) found at [PHPClasses](http://www.phpclasses.org). – madkris24 Mar 22 '11 at 22:44
-
[MaxMind GeoIP](http://www.maxmind.com/app/ip-location) is a good service. They also have a free city-level lookup service. – glomad Mar 22 '11 at 22:35
7 Answers
<?php
$user_ip = getenv('REMOTE_ADDR');
$geo = unserialize(file_get_contents("http://www.geoplugin.net/php.gp?ip=$user_ip"));
$country = $geo["geoplugin_countryName"];
$city = $geo["geoplugin_city"];
?>

- 721
- 8
- 8
-
5Geoplugin is not best platform. It is limited to 120 actions per minute. It worked for me, but lately it started to show 403 for all requests from my server. Who knows why. (I haven't made those 120 connections in one minute) – Mar 30 '17 at 17:18
-
4
Edited
Change freegeoip.net into ipinfo.io
<?php
function get_client_ip()
{
$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;
}
$PublicIP = get_client_ip();
$json = file_get_contents("http://ipinfo.io/$PublicIP/geo");
$json = json_decode($json, true);
$country = $json['country'];
$region = $json['region'];
$city = $json['city'];
?>

- 4,148
- 4
- 38
- 57
-
6While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value. – Jay Blanchard Apr 24 '17 at 19:31
-
1Is there a workaround for localhost servers? My ip address keeps coming up as ::1 – Vince Dec 25 '17 at 20:59
-
1
-
7__deprecation_message__: "This API endpoint is deprecated and will stop working on July 1st, 2018. For more information please visit: https://github.com/apilayer/freegeoip#readme", – Moses Schwartz May 23 '18 at 17:09
-
For what is it necessary to check all the forwarded ip? I thought only check `if(isset(HTTP_X_FORWARDED_FOR))` is necessary. – klediooo Jul 18 '19 at 17:32
-
1And in many countries this will get you the location of the ISP not the actual user – RiggsFolly Dec 02 '20 at 17:29
-
Found a free API https://ipapi.co/$PublicIP/json , or also single fields can be queried much quicker https://ipapi.co/$PublicIP/languages ! Check the docs at https://ipapi.co/api/#location-of-a-specific-ip – Hristo Apr 26 '22 at 06:28
<?php
$query = @unserialize (file_get_contents('http://ip-api.com/php/'));
if ($query && $query['status'] == 'success') {
echo 'Hey user from ' . $query['country'] . ', ' . $query['city'] . '!';
}
foreach ($query as $data) {
echo $data . "<br>";
}
?>
Try this code using this source. *It works!

- 30,738
- 21
- 105
- 131

- 866
- 8
- 12
-
8Do or do not. There is no "try". A ***good answer*** will always have an explanation of what was done and why it was done in such a manner, not only for the OP but for future visitors to SO. – Jay Blanchard Apr 24 '17 at 19:31
-
Try this code using the hostip.info service:
$country=file_get_contents('http://api.hostip.info/get_html.php?ip=');
echo $country;
// Reformat the data returned (Keep only country and country abbr.)
$only_country=explode (" ", $country);
echo "Country : ".$only_country[1]." ".substr($only_country[2],0,4);

- 7,361
- 1
- 44
- 52

- 101
- 1
- 2
-
1instead of exploding the return you can use the json as return. http://api.hostip.info/get_json.php – Underdog Oct 08 '14 at 11:56
-
$json_string = 'http://api.hostip.info/get_json.php?ip='.$_SERVER['REMOTE_ADDR']; $jsondata = file_get_contents($json_string); $obj = json_decode($jsondata, true); – Underdog Oct 08 '14 at 12:02
-
As PHP relies on a server, the real-time location can’t be provided. Only a static location can be provided. It is better to avoid to rely on the JavaScript for a location rather than using PHP.
But there is a need to post the JavaScript data to PHP, so that it can easily be accessible to a program on the server.

- 30,738
- 21
- 105
- 131

- 21
- 1
An IP address gives you a quite unreliable location. You could Ajax the location upon load with JavaScript if it isn't critical to have the location at first. (Also, the user needs to give you its permission to access it.)

- 30,738
- 21
- 105
- 131

- 3,049
- 6
- 23
- 37
-
1While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – Jay Blanchard Apr 24 '17 at 19:31
The old freegeoip API is now deprecated and will be discontinued on 2018-07-01.
The new API is from ipstack. You have to create the account in ipstack. Then you can use the access key in the API URL.
$url = "http://api.ipstack.com/122.167.180.20?access_key=ACCESS_KEY&format=1";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_PROXYPORT, 3128);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
curl_close($ch);
$response = json_decode($response);
$city = $response->city; // You can get all the details like longitude, latitude from the '$response'.
For more information, check at freegeoip (GitHub).

- 30,738
- 21
- 105
- 131

- 3,480
- 4
- 24
- 40