Для определения геолокации пользователя по IP будем использовать geoplugin.com.

Здесь все просто, вызываем: http://www.geoplugin.net/json.gp?ip={MY-IP}.

Где {MY-IP} - интересующий нас IP-адрес.

В ответ получил json массив следующего содержания:

{
  "geoplugin_request":"198.238.82.86",
  "geoplugin_status":206,
  "geoplugin_delay":"1ms",
  "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":"",
  "geoplugin_region":"",
  "geoplugin_regionCode":"",
  "geoplugin_regionName":"",
  "geoplugin_areaCode":"",
  "geoplugin_dmaCode":"",
  "geoplugin_countryCode":"US",
  "geoplugin_countryName":"United States",
  "geoplugin_inEU":0,
  "geoplugin_euVATrate":false,
  "geoplugin_continentCode":"NA",
  "geoplugin_continentName":"North America",
  "geoplugin_latitude":"37.751",
  "geoplugin_longitude":"-97.822",
  "geoplugin_locationAccuracyRadius":"1000",
  "geoplugin_timezone":"America\/Chicago",
  "geoplugin_currencyCode":"USD",
  "geoplugin_currencySymbol":"$",
  "geoplugin_currencySymbol_UTF8":"$",
  "geoplugin_currencyConverter":1
}

Остается только записать интересующие нас данные и использовать их в дальнейшем.

В примере будем использовать несколько параметров из ответа. И так напишем небольшой класс для получения IP-адреса пользователя и данных с geoplugin.net:

class GeoPRequest {

    public $userIp = '';
    public $city = 'unknown';
    public $state = 'unknown';
    public $country = 'unknown';
    public $countryCode = 'unknown';
    public $continent = 'unknown';
    public $continentCode = 'unknown';

    public function infoByIp() {

        if (filter_var($this->userIp, FILTER_VALIDATE_IP) === false) {
            $this->userIp = $_SERVER["REMOTE_ADDR"];
        }

        if ($this->userIp == '127.0.0.1') {
            $this->city = $this->state = $this->country = $this->countryCode = $this->continent = $this->countryCode = 'local machine';
        }

        if (filter_var($this->userIp, FILTER_VALIDATE_IP)) {
            $ipData = json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip=" . $this->userIp));

            if (strlen(trim($ipData->geoplugin_countryCode)) == 2) {
                $this->city = $ipData->geoplugin_city;
                $this->state = $ipData->geoplugin_regionName;
                $this->country = $ipData->geoplugin_countryName;
                $this->countryCode = $ipData->geoplugin_countryCode;
                $this->continent = $ipData->geoplugin_continentName;
                $this->continentCode = $ipData->geoplugin_continentCode;
            }

        }

        return $this;
    }

    public function getIp() {

        if (getenv('HTTP_CLIENT_IP')) {
            $this->userIp = getenv('HTTP_CLIENT_IP');
        } else if (getenv('HTTP_X_FORWARDED_FOR')) {
            $this->userIp = getenv('HTTP_X_FORWARDED_FOR');
        } else if (getenv('HTTP_X_FORWARDED')) {
            $this->userIp = getenv('HTTP_X_FORWARDED');
        } else if (getenv('HTTP_FORWARDED_FOR')) {
            $this->userIp = getenv('HTTP_FORWARDED_FOR');
        } else if (getenv('HTTP_FORWARDED')) {
            $this->userIp = getenv('HTTP_FORWARDED');
        } else if (getenv('REMOTE_ADDR')) {
            $this->userIp = getenv('REMOTE_ADDR');
        } else {
            $this->userIp = 'UNKNOWN';
        }

        return $this;
    }
}

Теперь вызовем наш класс и выведем то, что получили:

<?php
$userLocationData = new GeoPRequest();
$userLocationData->getIp()->infoByIp();
?>

<p>
    City: <?php echo  $userLocationData->city; ?>
State: <?php echo $userLocationData->state; ?>
Country: <?php echo $userLocationData->country; ?>
Continent: <?php echo $userLocationData->country; ?> <img src="https://www.countryflags.io/<?php echo strtolower($userLocationData->countryCode); ?>/flat/64.png" alt=""> </p>

Готово. Стоит обратить внимание на то, что при вызове с локального сервера, ваш IP будет 127.0.0.1 и вы получите ответ local machine.