Получение страны посетителей с их IP

Я хочу получить страну посетителей через их IP ... Сейчас я использую это (http://api.hostip.info/country.php?ip= ......)

Вот мой код:

<?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);

?>

Что ж, он работает правильно, но дело в том, что он возвращает код страны, такой как США или Калифорния, а не полное название страны, например США или Канада.

Итак, есть ли какая-нибудь хорошая альтернатива hostip.info, которая предлагает это?

Я знаю, что могу просто написать код, который в конечном итоге превратит эти две буквы в полное название страны, но мне просто лень писать код, содержащий все страны ...

P.S: По какой-то причине я не хочу использовать какой-либо готовый файл CSV или какой-либо код, который будет собирать эту информацию для меня, что-то вроде готового кода ip2country и CSV.


person Alex C.    schedule 23.09.2012    source источник
comment
Не поленитесь, стран не так много, и получить таблицу перевода буквенных кодов FIPS 2 в названия стран не так уж и сложно.   -  person Chris Henry    schedule 23.09.2012
comment
Используйте функцию Maxmind geoip. В результатах будет указано название страны. maxmind.com/app/php   -  person Tchoupi    schedule 23.09.2012
comment
Ваше первое присвоение $real_ip_address всегда игнорируется. В любом случае помните, что HTTP-заголовок X-Forwarded-For очень легко подделать, и что существуют прокси, такие как www.hidemyass.com   -  person Walter Tross    schedule 30.03.2014
comment
IPLocate.io предоставляет бесплатный API: https://www.iplocate.io/api/lookup/8.8.8.8 - Отказ от ответственности: я запускаю эту службу .   -  person ttarik    schedule 15.11.2017
comment
Я предлагаю попробовать Ipregistry: api.ipregistry.co/ (отказ от ответственности: я запускаю службу).   -  person Laurent    schedule 14.11.2019


Ответы (31)


Попробуйте эту простую функцию PHP.

<?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;
}

?>

Как использовать:

Пример 1. Получение сведений об IP-адресе посетителя

<?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 )

?>

Пример 2: Получите подробную информацию о любом IP-адресе. [Поддержка 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 )

?>
person Chandra Nakka    schedule 28.11.2012
comment
почему я все время становлюсь неизвестным с каждым ip? , использовал тот же код. - person echo_Me; 18.02.2014
comment
Вы получаете "Неизвестно", вероятно, потому, что ваш сервер не разрешает file_get_contents(). Просто проверьте свой файл error_log. Решение: см. Мой ответ. - person Avatar; 19.02.2014
comment
также это может быть потому, что вы проверяете его локально (192.168.1.1 / 127.0.0.1 / 10.0.0.1) - person Hontoni; 02.05.2014
comment
@EchtEinfachTV Я тоже не могу получить название страны, когда я повторяю $ cip, $ iptolocation и $ creatorlocation, я получаю следующее: 10.48.44.43http: //api.hostip.info/country.php? Ip = 10.48.44.43XX , почему он возвращает xx для страны? - person mOna; 21.09.2014
comment
@Antonimo: Я тоже не могу получить название страны, когда я повторяю $ cip, $ iptolocation и $ creatorlocation, я получаю следующее: 10.48.44.43http: //api.hostip.info/country.php? Ip = 10.48.44.43 XX, почему он возвращает xx для страны? - - person mOna; 21.09.2014
comment
все, что начинается с 10. - это локальный ip, проверьте manuals / wiki - person Hontoni; 22.09.2014
comment
@echo_Me Возможно, вашему серверу не удалось подключиться к geoplugin.net серверу API. - person Chandra Nakka; 23.09.2014
comment
Продолжайте получать "undefined" для моей страны - person madcrazydrumma; 15.04.2015
comment
@madcrazydrumma Какой у вас IP? - person Chandra Nakka; 15.04.2015
comment
@ChandraNakka 127.0.0.1 - это локальный сервер, мой IP-адрес в настоящее время - 197.234.10.142, который должен находиться на Сейшельских островах. - person madcrazydrumma; 15.04.2015
comment
Не забудьте кэшировать результаты за определенный период. Также, как примечание, вы никогда не должны полагаться на другой веб-сайт для получения каких-либо данных, веб-сайт может выйти из строя, служба может остановиться и т. Д. И если вы получите увеличенное количество посетителей на вашем веб-сайте, эта услуга может заблокировать вас. - person machineaddict; 19.06.2015
comment
Требуется ли для этого авторизация пользователя, как это делала геолокация? - person 4 Leave Cover; 11.11.2016
comment
echo ip_info (посетитель, код страны); возвращает NULL - person Nick; 06.02.2017
comment
Следуйте дальше: это проблема при тестировании сайта на localhost. Есть ли способ исправить в целях тестирования? Использует стандартный IP 127.0.0.1 localhost - person Nick; 06.02.2017
comment
Работал на МЕНЯ. Спасибо. - person Vignesh Chinnaiyan; 21.05.2018
comment
Следует отметить, что HTTP_X_FORWARDED_FOR и HTTP_CLIENT_IP, используемые в опции deep_detect, дадут вам реальный IP-адрес пользователя, если он использует прокси-сервер -прозрачный прокси offcurse -, а не IP-адрес прокси-сервера, который это клиент, как на самом деле tcp-подключен к моему сайту. Спасибо за отличный ответ - person Accountant م; 12.01.2019
comment
Я не могу заставить это работать. Я скопировал функцию и попробовал первый пример, и на странице нет ни одного эха или печати. - person bleah1; 24.09.2019
comment
Это круто, я давно искал что-то подобное, молодец! - person Ryan D; 20.10.2019
comment
Он использует ссылку на объект - ›но вместо этого нужно изменить массив на ['']. Также следует избавиться от всего этого @ подавления. Кроме того, использование curl намного лучше, чем file_get_contents. - person steve moretz; 07.02.2021

Вы можете использовать простой API из 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 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;
}

Выход

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

Это дает вам так много вариантов, с которыми вы можете поиграть

Спасибо

:)

person Baba    schedule 23.09.2012
comment
Это действительно круто. Но при тестировании здесь нет значений в следующих полях geoplugin_city, geoplugin_region, geoplugin_regionCode, geoplugin_regionName .. В чем причина? Есть какое-нибудь решение? заранее спасибо - person M B Parvez Rony; 28.02.2015
comment
теперь это geoplugin.com .... который .... вы, вероятно, можете сослаться на другой пример (выше) - person Malachi; 08.10.2020

Я попробовал ответ Чандры, но конфигурация моего сервера не позволяет использовать file_get_contents ()

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

Я изменил код Чандры, чтобы он работал и на таких серверах, используя 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

?>

Надеюсь, это поможет ;-)

person Avatar    schedule 19.02.2014
comment
Согласно документации на их сайте: если geoplugin.net отлично отвечал, а затем остановился, значит, вы превысили лимит бесплатного поиска в 120 запросов в минуту. - person Rick Hellewell; 02.09.2019
comment
Работает красиво. Спасибо! - person Najeeb; 29.05.2020

Вы можете использовать веб-службу из http://ip-api.com
в своем PHP-коде , сделайте следующее:

<?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';
}
?>

в запросе есть много другой информации:

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',
)
person Halayem Anis    schedule 05.10.2014
comment
Используется ip-api.com, потому что они также предоставляют имя интернет-провайдера! - person Richard Tinkler; 11.05.2016
comment
Я использовал, потому что они также предоставляют часовой пояс - person Roy Shoa; 10.09.2017

Фактически, вы можете позвонить http://api.hostip.info/?ip=123.125.114.144 для получения информации, представленной в XML.

person Marcus    schedule 23.09.2012

Используйте MaxMind GeoIP (или GeoIPLite, если вы не готовы платить).

$gi = geoip_open('GeoIP.dat', GEOIP_MEMORY_CACHE);
$country = geoip_country_code_by_addr($gi, $_SERVER['REMOTE_ADDR']);
geoip_close($gi);
person Joyce Babu    schedule 23.09.2012
comment
@Joyce: Я пытался использовать Maxmind API и DB, но я не знаю, почему это не работает для меня, на самом деле это работает в целом, но, например, когда я запускаю этот $ _SERVER ['REMOTE_ADDR']; он показывает мне этот ip: 10.48.44.43, но когда я использую его в geoip_country_code_by_addr ($ gi, $ ip), он ничего не возвращает, какая-нибудь идея? - person mOna; 21.09.2014
comment
Это зарезервированный IP-адрес (внутренний IP-адрес из вашей локальной сети). Попробуйте запустить код на удаленном сервере. - person Joyce Babu; 21.09.2014

Воспользуйтесь следующими услугами

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

2)

$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

person GBD    schedule 23.09.2012

Проверьте php-ip-2-country на code.google. Предоставляемая ими база данных обновляется ежедневно, поэтому нет необходимости подключаться к внешнему серверу для проверки, если вы размещаете свой собственный SQL-сервер. Таким образом, используя код, вам нужно будет только ввести:

<?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;
?>

Пример кода (из ресурса)

<?
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));
?>

Вывод

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
)
person AbsoluteƵERØ    schedule 13.11.2013
comment
мы должны предоставить информацию о базе данных для работы? кажется не очень хорошо. - person echo_Me; 16.02.2014

Мы можем использовать geobytes.com для получения местоположения по IP-адресу пользователя.

$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);

он вернет такие данные

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
)

Функция получения 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;
}
person Ram Sharma    schedule 25.08.2014
comment
Я пробовал ваш код, он мне возвращает: Array ([known] = ›false) - person mOna; 20.09.2014
comment
когда я пробую это: $ ip = $ _SERVER [REMOTE_ADDR]; эхо $ ip; он возвращает это: 10.48.44.43, вы знаете, в чем проблема ?? Я использовал alspo maxmind geoip, и когда я снова использовал geoip_country_name_by_addr ($ gi, $ ip), он ничего мне не вернул ... - person mOna; 20.09.2014
comment
@mOna, он вернет ваш IP-адрес. для получения более подробной информации, пожалуйста, поделитесь своим кодом. - person Ram Sharma; 22.09.2014
comment
Я обнаружил, что проблема связана с моим IP-адресом, поскольку он предназначен для частной сети. Затем я ввожу свой реальный IP-адрес в ifconfig и использую его в своей программе. потом это сработало :) Теперь у меня вопрос, как получить реальный ip в случае таких пользователей, как я? (если они используют локальный IP-адрес) .. Я написал свой код здесь: stackoverflow.com/questions/25958564/ - person mOna; 22.09.2014

Попробуйте этот простой однострочный код, вы получите страну и город посетителей с их удаленного IP-адреса.

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


Множество разных способов сделать это ...

Решение №1:

Вы можете использовать стороннюю службу http://ipinfodb.com. Они предоставляют имя хоста, геолокацию и дополнительную информацию.

Зарегистрируйтесь для получения ключа API здесь: http://ipinfodb.com/register.php. Это позволит вам получать результаты со своего сервера, без этого он не будет работать.

Скопируйте и вставьте следующий код PHP:

$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'];

Обратная сторона:

Цитата с их веб-сайта:

Наш бесплатный API использует версию IP2Location Lite, которая обеспечивает более низкую точность.

Решение №2:

Эта функция вернет название страны с помощью службы http://www.netip.de/.

$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));

Вывод:

Array ( [country] => DE - Germany )  // Full Country Name
person imbondbaby    schedule 09.07.2014
comment
Цитата с их веб-сайта: вы ограничены 1000 запросами API в день. Если вам нужно сделать больше запросов или нужна поддержка SSL, ознакомьтесь с нашими платными планами. - person Walter Tross; 10.07.2014
comment
Я использовал его на своем личном сайте, поэтому разместил его. Спасибо за информацию ... не осознал. Я приложил гораздо больше усилий к публикации, поэтому просмотрите обновленную публикацию :) - person imbondbaby; 10.07.2014
comment
@imbondbaby: Привет, я пробовал ваш код, но для меня он возвращает следующее: Array ([country] = ›-), я не понимаю проблемы, поскольку, когда я пытаюсь напечатать это: $ ipaddress = $ _SERVER ['REMOTE_ADDR' ]; он показывает мне этот ip: 10.48.44.43, я не могу понять, почему этот ip не работает! Я имею в виду, что где бы я ни вставлял этот номер, он не возвращает ни одной страны !!! Посоветуйте, пожалуйста, помогите мне? - person mOna; 21.09.2014

Моя служба ipdata.co предоставляет название страны на 5 языках! А также организация, валюта, часовой пояс, телефонный код, флаг, данные мобильного оператора, данные прокси и данные статуса выходного узла Tor с любого адреса IPv4 или IPv6.

В этом ответе используется «тестовый» API-ключ, который очень ограничен и предназначен только для тестирования нескольких вызовов. Зарегистрируйтесь для получения собственного бесплатного ключа API и получать до 1500 запросов в день на разработку.

Он также чрезвычайно масштабируем с 10 регионами по всему миру, каждый из которых может обрабатывать> 10 000 запросов в секунду!

Варианты включают; Английский (en), немецкий (de), японский (ja), французский (fr) и упрощенный китайский (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;
//美国
person Jonathan    schedule 05.09.2017
comment
Да благословит тебя Бог, мужик! Я получил больше, чем просил! Быстрый вопрос: могу ли я использовать его для продакшена? Я имею в виду, ты не собираешься откладывать это в ближайшее время, не так ли? - person Sayed; 22.11.2017
comment
Вовсе нет :) На самом деле я добавляю больше регионов и больше полировки. Рад, что вы нашли это полезным :) - person Jonathan; 22.11.2017
comment
Очень полезно, особенно с дополнительными параметрами, решило для меня более одной проблемы! - person Sayed; 22.11.2017
comment
Спасибо за положительный отзыв! Я построил вокруг наиболее распространенных вариантов использования такого инструмента, цель состояла в том, чтобы исключить необходимость дополнительной обработки после геолокации, и я был рад видеть, что это окупается для пользователей. - person Jonathan; 22.11.2017

Не уверен, что это новая служба, но сейчас (2016 г.) самый простой способ на php - использовать веб-службу php geoplugin: http://www.geoplugin.net/php.gp:

Базовое использование:

// 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));

Они также предоставляют готовый встроенный класс: http://www.geoplugin.com/_media/webservices/geoplugin.class.php.tgz?id=webservices%3Aphp&cache=cache

person billynoah    schedule 17.06.2016
comment
Вы использовали else после else, что вызывает ошибку. Что вы пытались предотвратить? REMOTE_ADDR должен быть доступен постоянно? - person AlexioVay; 27.10.2016
comment
@Vaia - Возможно, это должно быть, но мало ли. - person billynoah; 14.11.2016
comment
Известен ли вам случай, когда он недоступен? - person AlexioVay; 14.11.2016
comment
@Vaia - из документации PHP на $_SERVER: Нет гарантии, что каждый веб-сервер предоставит что-либо из этого; серверы могут опускать некоторые или предоставлять другие, не перечисленные здесь. - person billynoah; 14.11.2016
comment
Обратите внимание: количество запросов ограничено; со своего сайта: Если geoplugin.net отлично отвечал, а затем остановился, значит, вы превысили лимит бесплатного поиска в 120 запросов в минуту. - person Rick Hellewell; 02.09.2019

вы можете использовать http://ipinfo.io/, чтобы получить подробную информацию об IP-адресе. Его легко использовать.

<?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; /

    ?>
person Aqib1604    schedule 02.10.2014

Один лайнер с IP-адресом для страны API

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

> United States

Пример :

https://ipapi.co/country_name/ - ваша страна

https://ipapi.co/8.8.8.8/country_name/ - страна для IP 8.8 .8.8

person user6885709    schedule 08.02.2018
comment
Этот API позволяет 1000 (бесплатных) вызовов API в день. - person reformed; 21.05.2018

Я использую ipinfodb.com api и получаю именно то, что вы ищете.

Это совершенно бесплатно, вам просто нужно зарегистрироваться у них, чтобы получить свой ключ api. Вы можете включить их php-класс, загрузив его с их веб-сайта, или вы можете использовать формат URL-адреса для получения информации.

Вот что я делаю:

Я включил их php-класс в свой скрипт и использовал следующий код:

$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'];

Вот и все.

person Miraj    schedule 03.09.2014

Замените 127.0.0.1 на IpAddress посетителей.

$country = geoip_country_name_by_name('127.0.0.1');

Инструкции по установке находятся здесь, а прочтите это, чтобы узнать, как получить город, штат, страну, долготу, широту и т. д.

person Jack M.    schedule 01.11.2014
comment
Пожалуйста, предоставьте больше актуального кода, чем просто жесткие ссылки. - person Bram Vanroy; 09.05.2017
comment
Более поздние новости по ссылке: 2 января 2019 года Maxmind прекратил поддержку исходных баз данных GeoLite, которые мы использовали во всех этих примерах. Вы можете прочитать полное объявление здесь: support.maxmind.com/geolite-legacy-discontinuation -notice - person Rick Hellewell; 02.09.2019

У меня есть короткий ответ, который я использовал в проекте. В своем ответе я считаю, что у вас есть IP-адрес посетителя.

$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;
}
person Shahbaz    schedule 06.01.2016

Было бы это приемлемо? чистый PHP

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

ссылка: https://www.php.net/manual/en/function.geoip-country-code-by-name.php

person pc_    schedule 21.06.2020
comment
обратите внимание, что это работает только с установленным расширением GeoIP PECL для PHP (которое по умолчанию не входит в комплект). - person richey; 07.09.2020

Я знаю, что это устарело, но я пробовал здесь несколько других решений, и они кажутся устаревшими или просто возвращают значение null. Вот как я это сделал.

Использование http://www.geoplugin.net/json.gp?ip=, которое не требует какой-либо регистрации или оплаты услуг.

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);

И если вам нужна дополнительная информация об этом, это полный возврат 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
}
person Jayce    schedule 31.03.2019

Я написал урок, основанный на ответе «Чандра Накка». Надеюсь, это может помочь людям, так как сохраняет информацию из геоподключаемого модуля в сеанс, поэтому загрузка при вызове информации происходит намного быстрее. Он также сохраняет значения в частном массиве, поэтому вызов в том же коде является самым быстрым из возможных.

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;
}
}

Отвечая на вопрос "op" с этим классом, вы можете позвонить

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

И другие доступные свойства:

$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'));

Возвращение

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) "£"
person royalwebs    schedule 04.03.2020

В User Country API есть именно то, что вам нужно. Вот пример кода, использующего file_get_contents (), как вы это делаете изначально:

$result = json_decode(file_get_contents('http://usercountry.com/v1.0/json/'.$cip), true);
$result['country']['name']; // this contains what you need
person byl83    schedule 10.08.2017
comment
Этот API позволяет выполнять 100 (бесплатных) вызовов API в день. - person reformed; 21.05.2018

Вы можете узнать страну и город посетителей с помощью ipstack geo API. Вам нужно получить свой собственный ipstack API, а затем использовать приведенный ниже код:

<?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 ."";
?>

Источник: Привлечь посетителей страна и город в PHP с использованием ipstack API

person Faruque Ahamed Mollick    schedule 13.07.2018

Это просто примечание по безопасности относительно функциональности get_client_ip(), поскольку большинство ответов здесь было включено в основную функцию get_geo_info_for_this_ip().

Не полагайтесь слишком сильно на IP-данные в заголовках запросов, таких как Client-IP или X-Forwarded-For, потому что их можно очень легко подделать, однако вам следует полагаться на исходный IP-адрес TCP-соединения, которое фактически установлено между нашим сервером и клиентом $_SERVER['REMOTE_ADDR'], поскольку его нельзя подделать

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

Можно получить страну поддельного IP-адреса, но имейте в виду, что использование этого IP-адреса в любой модели безопасности (например, запрет IP-адреса, который отправляет частые запросы) разрушит всю модель безопасности. ИМХО, я предпочитаю использовать фактический IP-адрес клиента, даже если это IP-адрес прокси-сервера.

person Accountant م    schedule 12.01.2019

Пытаться

  <?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;

  ?>
person Dipanshu Mahla    schedule 06.04.2019
comment
Часть if-else даст вам IP-адрес посетителя, а следующая часть вернет код страны. Попробуйте посетить api.wipmania.com, а затем api.wipmania.com/ [ваш_IP_адрес] - person Dipanshu Mahla; 07.04.2019

Вы можете использовать мой сервис: https://SmartIP.io, который предоставляет полные названия стран и городов любого IP-адреса. . Мы также предоставляем часовые пояса, валюту, обнаружение прокси, обнаружение узлов TOR и обнаружение криптографии.

Вам просто нужно зарегистрироваться и получить бесплатный ключ API, который позволяет обрабатывать 250 000 запросов в месяц.

Используя официальную библиотеку PHP, вызов API становится:

$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"};

Дополнительную информацию см. В документации по API: https://smartip.io/docs

person kevinj    schedule 15.08.2019

По состоянию на 2019 год страновая БД MaxMind может использоваться следующим образом:

<?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();

Источник: https://github.com/maxmind/MaxMind-DB-Reader-php < / а>

person Pedro Lobito    schedule 06.12.2019

Код PHP для получения страны, города,
континента и т. Д. С использованием IP-адреса

    $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; 
person Arsalan Ahmed    schedule 23.09.2020

Вот более чистая и рабочая версия принятого ответа с использованием guzzle:

Вы можете использовать curl вместо жрать, это просто простой запрос на получение.

    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;
    }
person steve moretz    schedule 07.02.2021

Если вам нужно получить страну как можно быстрее, я бы предложил плагин geoip для вашего веб-сервера.

Для nginx здесь;

После правильной настройки вы получите код страны из переменной $_SERVER.

Я выполняю это примерно 500 (+ -) раз в секунду, очень быстро.

person temo    schedule 07.04.2021