1

I'm trying to use the geoplugin to get the users gelocation and city in PHP.

However, when i run this code I get the following error:

Notice: unserialize(): Error at offset 0 of 172 bytes in ndex.php on line 21

This is my entire code:

$user_ip = getenv('REMOTE_ADDR');
echo $user_ip;
$geo = unserialize(file_get_contents("http://www.geoplugin.net/php.gp?ip=".$user_ip.""));
$city = $geo["geoplugin_city"];
$region = $geo["geoplugin_regionName"];
$country = $geo["geoplugin_countryName"];
echo "City: ".$city."<br>";
echo "Region: ".$region."<br>";
echo "Country: ".$country."<br>";

and the line 21 that is shown in the error is this:

$geo = unserialize(file_get_contents("http://www.geoplugin.net/php.gp?ip=".$user_ip.""));

I have used this code on other server and worked just fine but on a new server I get that error which I have no idea why.

could someone please advise on this issue?

any help would be appreciated.

EDIT:

I edited my code to the following and still get the same error:

$user_ip = getenv('REMOTE_ADDR');


$geo = file_get_contents("http://www.geoplugin.net/php.gp?ip=".$user_ip."");
$string = preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $geo);
$geo = unserialize($string);

$city = $geo["geoplugin_city"];
$region = $geo["geoplugin_regionName"];
$country = $geo["geoplugin_countryName"];
echo "City: ".$city."<br>";
echo "Region: ".$region."<br>";
echo "Country: ".$country."<br>";
rooz
  • 361
  • 1
  • 8
  • 22
  • 2
    Did you checked what file get contents return? May be it server problem – Andrey Mussatov Jan 07 '16 at 12:56
  • everything is ok with your code. I get full response: https://www.dropbox.com/s/n2xzt01isbpdcn8/Screenshot%202016-01-07%2014.03.28.png?dl=0 – iWizard Jan 07 '16 at 13:03
  • @AndreyMussatov, i did ` var_dump($geo) ` and I get this on page: `bool(false) ` – rooz Jan 07 '16 at 13:05
  • @CroiOS, i know because i use the same code on another server without any issues so the issue is from the server i think but i don't know what could be the cause of this issue! – rooz Jan 07 '16 at 13:06
  • Consider using another IP info service, like: http://ipinfo.io/ – segFault Jan 07 '16 at 13:06
  • make var_dump(file_get_contents("http://www.geoplugin.net/php.gp?ip=".$user_ip."")) may be you should use CURL. – Andrey Mussatov Jan 07 '16 at 13:08
  • @AndreyMussatov, i get a 403 Forbidden error now using your code. – rooz Jan 07 '16 at 13:18
  • So basically the generation of the string done by `www.geoplugin.net` is incorrect as it does not take into account the multi byte nature of `geoplugin_currencySymbol_UTF8` which as it has a name that includes the word `UTF-8` is a little disappointing – RiggsFolly Jan 07 '16 at 13:28
  • I hope from now you know what to do. (read geoplugin.net FAQ) – Andrey Mussatov Jan 07 '16 at 13:28
  • I changed the url to request JSON and that works with a `json_decode()` of course `file_get_contents("http://www.geoplugin.net/json.gp?ip=".$user_ip` – RiggsFolly Jan 07 '16 at 13:34
  • @RiggsFolly, I have no idea what you just explained. sorry. I understand that the currency symbol is some how causing the issue but I'm not sure how and why and how to solve it. – rooz Jan 07 '16 at 13:35
  • The currency symbol is being passed as UTF-8 multibyte char set, but the serialization done at the geoplugin end is not reporting that that string is the correct multibyte length its reporting it as if it was a single byte character, so the unserialize is failing – RiggsFolly Jan 07 '16 at 13:37
  • @RiggsFolly, ok, so what is the solution to this (other than using json)? – rooz Jan 07 '16 at 13:44
  • Well I guess you could get geoplugin to fix their end where the problem is or you could upgrade to PHP5.6 as that seems to cope with it better – RiggsFolly Jan 07 '16 at 13:47
  • my Current PHP version is 5.4.42 – rooz Jan 07 '16 at 13:49

1 Answers1

1

The output from that URL doesn't appear to be serialized correctly, at least for UK based IP addresses - I tested by manually going to the URL:

http://www.geoplugin.net/php.gp?ip=81.201.130.8

Which gives:

a:18:{s:17:"geoplugin_request";s:12:"81.201.130.8";s:16:"geoplugin_status";i:206;s:16:"geoplugin_credit";s:145:"Some of the returned data includes GeoLite data created by MaxMind, available from <a href=\'http://www.maxmind.com\'>http://www.maxmind.com</a>.";s:14:"geoplugin_city";s:0:"";s:16:"geoplugin_region";s:0:"";s:18:"geoplugin_areaCode";s:1:"0";s:17:"geoplugin_dmaCode";s:1:"0";s:21:"geoplugin_countryCode";s:2:"GB";s:21:"geoplugin_countryName";s:14:"United Kingdom";s:23:"geoplugin_continentCode";s:2:"EU";s:18:"geoplugin_latitude";s:4:"51.5";s:19:"geoplugin_longitude";s:5:"-0.13";s:20:"geoplugin_regionCode";s:0:"";s:20:"geoplugin_regionName";N;s:22:"geoplugin_currencyCode";s:3:"GBP";s:24:"geoplugin_currencySymbol";s:6:"&#163;";s:29:"geoplugin_currencySymbol_UTF8";s:2:"£";s:27:"geoplugin_currencyConverter";s:6:"0.6834";}

Pasting that into an online unserializer (such as http://blog.tanist.co.uk/files/unserialize/) confirms it's not working - I think it's becuase it's treating the pound sign as 2 characters (as it's UTF-8) - If I replace s:2:"£" with s:1:"£" it unserializes correctly.

Liam Wiltshire
  • 1,254
  • 13
  • 26
  • Works perfectly for my UK ipaddress, it does not provide much actual data though – RiggsFolly Jan 07 '16 at 13:07
  • I am able to properly unserialize the results using IP: "81.201.130.8" – segFault Jan 07 '16 at 13:09
  • Out of interest, what version of PHP is everyone using?? I am using 5.6.15 all version 5.5.30 and older seem to have problems with the `geoplugin_currencySymbol_UTF8` field. Understandable really – RiggsFolly Jan 07 '16 at 13:19
  • the issue is that the exact same code works absolutely fine on another server! – rooz Jan 07 '16 at 14:13