1

Context:

I want to detect the two letter continent code of my user(s) to allow me to conditionally display an American or more general phone number.

E.g. If continent code is North America or South America, display North American phone number. Else, display general international phone number.

What I've tried:

  1. A similar question on Stack Overflow was resolved using a light-weight function however in my case, the function did not output anything (i.e. blank).
  2. The PHP manual lists the geoip_continent_code_by_name function of GEOIP extension however installation of this extension seems overkill and besides, I'm in no way familiar with command line installs for WHM/cPanel.

My question:

Is there an easier and lighter-weight method of detecting the two-letter continent code by IP?

Community
  • 1
  • 1
Clarus Dignus
  • 3,847
  • 3
  • 31
  • 57
  • You can look this function : http://php.net/manual/fr/function.geoip-continent-code-by-name.php. You need to install PECL Geoip. – Vincent Decaux Mar 30 '16 at 12:07
  • 1
    In attempt 1 did you check the error log? Blank output can be caused by an error... or you could try running a `whois` on the IP. – chris85 Mar 30 '16 at 12:08
  • @chris85 The only error pertains to attempt 2 (fatal error, call to undefined function). – Clarus Dignus Mar 30 '16 at 12:12
  • @chris85 I copied and pasted the code as is to a test document in the public directory root of my website (WordPress root): http://pastebin.com/Tv07rr7D – Clarus Dignus Mar 30 '16 at 12:18
  • 1
    The first value of that function call should be the IP, did you change that? Testing locally I did `$ipinfo = ip_info('50.203.165.214'); echo $ipinfo['country_code'];` and it works for me. – chris85 Mar 30 '16 at 12:19
  • @chris85 I didn't however defining the `$ipinfo variable` as you've instructed produces the same result in my case. I.e. Blank. – Clarus Dignus Mar 30 '16 at 12:34
  • @chris85 Yes (http://pastebin.com/fbp1yP7S). I suspect that WordPress may be obstructing the output. I'll text the function locally to confirm. – Clarus Dignus Mar 30 '16 at 12:39
  • @chris85 The output at your link works correctly however the same code does not produce an output on my website or locally. http://pastebin.com/WkxEiDtQ – Clarus Dignus Mar 30 '16 at 12:55
  • 1
    Those `echo`s are all useless. The `Visitor` needs to be the IP, `$_SERVER['REMOTE_ADDR']`..or `print_r($ipinfo);` – chris85 Mar 30 '16 at 14:48
  • @chris85 Having applied your correction, it now works locally however the output is still blank when I apply it to my root directory of theme files of WordPress website. This is likely a separate issue that I'll need to debug independently. E.g. Security restrictions etc. – Clarus Dignus Mar 30 '16 at 15:31
  • I opted for a WordPress plugin solution that resolved my issue: https://wordpress.org/plugins/geoip-detect/ It incorporates the MaxMind GeoIP data sources and conditionally applies classes to the body tags of my website pages which perfectly serves my original purpose. – Clarus Dignus Mar 30 '16 at 21:14

2 Answers2

2

You can use official API by MaxMind https://maxmind.github.io/GeoIP2-php/

example of code

<?php 

require_once 'vendor/autoload.php';
use GeoIp2\Database\Reader;

// This creates the Reader object, which should be reused across
// lookups.
$reader = new Reader('GeoLite2-Country.mmdb');

// Replace "city" with the appropriate method for your database, e.g.,
// "country".
$record = $reader->country('128.101.101.101');

echo ($record->continent->code);
dmeleshko
  • 31
  • 5
  • I opted for WordPress plugin that already has various MaxMind data sources baked in: https://wordpress.org/plugins/geoip-detect/ – Clarus Dignus Mar 30 '16 at 21:16
1

You can use this function:

function get_continent_by_ip($ip = false) {
    $code = false;

    if (!$ip) {
        $client = @$_SERVER['HTTP_CLIENT_IP'];
        $forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
        $remote = @$_SERVER['REMOTE_ADDR'];

        if (filter_var($client, FILTER_VALIDATE_IP)) {
            $ip = $client;
        } elseif (filter_var($forward, FILTER_VALIDATE_IP)) {
            $ip = $forward;
        } else {
            $ip = $remote;
        }
    }

    $response = @json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip={$ip}"));    

    if ($response && isset($response->geoplugin_continentCode)) {
        $code = $response->geoplugin_continentCode;
    }

    return $code;
}

It detects IP of user and returns code of continent

  • As per my previous attempts, the result is blank. No errors logged. – Clarus Dignus Mar 30 '16 at 12:36
  • Maybe your ip isn't detected. You can test function with IP of google.com: `get_continent_by_ip('8.8.8.8');` – Alexander Maximiuk Mar 30 '16 at 12:45
  • Blank on my website and locally: http://pastebin.com/bzVcBT38 I.e. Two separate environments. – Clarus Dignus Mar 30 '16 at 13:02
  • It is not correct. Try: `print get_continent_by_ip('8.8.8.8');` or `$code = get_continent_by_ip('8.8.8.8'); print $code;` – Alexander Maximiuk Mar 30 '16 at 13:05
  • Locally, the result is "NA". On my website, the result is still blank. Again, to reiterate, it is my concern that WordPress may be restricting the output of my website. It's not an issue locally because my PHP document isn't residing within a WordPress directory. That's the only educated guess I can attempt to explain the difference in behavior. – Clarus Dignus Mar 30 '16 at 13:29