Pozyskiwanie użytkowników z ich kraju


220

Chcę, aby odwiedzający kraj był dostępny za pośrednictwem adresu IP ... Teraz korzystam z tego ( http://api.hostip.info/country.php?ip= ......)

Oto mój kod:

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

?>

Cóż, działa poprawnie, ale chodzi o to, że zwraca kod kraju jak USA lub Kalifornia, a nie całą nazwę kraju jak Stany Zjednoczone czy Kanada.

Czy jest jakaś dobra alternatywa dla hostip.info?

Wiem, że mogę po prostu napisać kod, który ostatecznie przekształci te dwie litery w nazwę całego kraju, ale jestem zbyt leniwy, aby napisać kod zawierający wszystkie kraje ...

PS: Z jakiegoś powodu nie chcę używać żadnego gotowego pliku CSV ani żadnego kodu, który pobierze te informacje, coś w rodzaju gotowego kodu ip2country i CSV.


20
Nie bądź leniwy, nie ma tak wielu krajów i nie jest zbyt trudno uzyskać tabelę tłumaczeń kodów literowych FIPS 2 na nazwy krajów.
Chris Henry

Użyj funkcji geoip Maxmind. W wynikach pojawi się nazwa kraju. maxmind.com/app/php
Tchoupi

Twoje pierwsze zadanie do $real_ip_addressjest zawsze ignorowane. W każdym razie pamiętaj, że X-Forwarded-Fornagłówek HTTP można bardzo łatwo podrobić i że istnieją serwery proxy takie jak www.hidemyass.com
Walter Tross

5
IPLocate.io zapewnia bezpłatny interfejs API: https://www.iplocate.io/api/lookup/8.8.8.8- Oświadczenie: uruchamiam tę usługę.
ttarik

Sugeruję wypróbowanie Ipregistry : api.ipregistry.co/… (zrzeczenie się odpowiedzialności: prowadzę usługę).
Laurent

Odpowiedzi:


495

Wypróbuj tę prostą funkcję 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;
}

?>

Jak używać:

Przykład 1: Uzyskaj szczegóły adresu IP użytkownika

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

?>

Przykład 2: Uzyskaj szczegółowe informacje na temat dowolnego adresu IP. [Wsparcie IPV4 i 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 )

?>

1
dlaczego cały czas się nie dowiem przy każdym IP? , używał tego samego kodu.
echo_Me

1
Otrzymujesz komunikat „Nieznany” prawdopodobnie dlatego, że Twój serwer nie pozwala file_get_contents(). Po prostu sprawdź plik dziennika error_log. Obejście: patrz moja odpowiedź.
Kai Noack,

3
może być również dlatego, że sprawdzasz go lokalnie (192.168.1.1 / 127.0.0.1 / 10.0.0.1)
Hontoni

1
Pamiętaj, aby buforować wyniki przez określony czas. Pamiętaj też, że nigdy nie powinieneś polegać na innej witrynie internetowej w celu uzyskania jakichkolwiek danych, witryna może ulec awarii, usługa może zostać zatrzymana itp. A jeśli zwiększysz liczbę odwiedzających witrynę, usługa ta może Cię zablokować.
machineaddict

1
Kontynuuj: jest to problem podczas testowania witryny na localhost. Jakiś sposób naprawić do celów testowych? Używa standardowego adresu IP hosta lokalnego 127.0.0.1
Nick

54

Możesz użyć prostego API z 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>";

Używana funkcja

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

Wynik

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

Dzięki temu masz tyle opcji, z którymi możesz się bawić

Dzięki

:)


1
To jest naprawdę fajne. Ale podczas testowania tutaj nie ma wartości w następujących polach „geoplugin_city, geoplugin_region, geoplugin_regionCode, geoplugin_regionName” .. Jaki jest powód? Czy jest jakieś rozwiązanie? Z góry
dziękuję

31

Próbowałem odpowiedzi Chandry, ale moja konfiguracja serwera nie zezwala na file_get_contents ()

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

Zmodyfikowałem kod Chandry, aby działał również na serwerach podobnych do tego przy użyciu 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

?>

Mam nadzieję, że to pomaga ;-)


1
Według dokumentów na ich stronie: „Jeśli geoplugin.net odpowiedział doskonale, to zatrzymał się, to przekroczyłeś limit bezpłatnego wyszukiwania wynoszący 120 żądań na minutę.”
Rick Hellewell

Działał pięknie. Dzięki!
Najeeb


11

Użyj MaxMind GeoIP (lub GeoIPLite, jeśli nie jesteś gotowy do zapłaty).

$gi = geoip_open('GeoIP.dat', GEOIP_MEMORY_CACHE);
$country = geoip_country_code_by_addr($gi, $_SERVER['REMOTE_ADDR']);
geoip_close($gi);

@Joyce: Próbowałem użyć Maxmind API i DB, ale nie wiem, dlaczego to nie działa dla mnie, faktycznie działa ogólnie, ale na przykład, kiedy uruchamiam $ _SERVER ['REMOTE_ADDR']; pokazuje mi ten ip: 10.48.44.43, ale kiedy używam go w geoip_country_code_by_addr ($ gi, $ ip), nie zwraca nic, jakiś pomysł?
mOna

Jest to zarezerwowany adres IP (wewnętrzny adres IP z sieci lokalnej). Spróbuj uruchomić kod na zdalnym serwerze.
Joyce Babu,


10

Sprawdź php-ip-2-country na code.google. Baza danych, którą zapewniają, jest aktualizowana codziennie, więc nie jest konieczne łączenie się z zewnętrznym serwerem w celu sprawdzenia, czy hostujesz własny serwer SQL. Więc używając kodu wystarczy wpisać:

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

Przykładowy kod (z zasobu)

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

Wynik

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
)

4
musimy podać informacje z bazy danych, aby działać? wydaje się źle.
echo_Me

10

Możemy użyć geobytes.com, aby uzyskać lokalizację przy użyciu adresu IP użytkownika

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

zwróci takie dane

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
)

Funkcja uzyskiwania adresu IP użytkownika

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

Próbowałem twój kod, zwraca mi to: Array ([znane] => false)
mOna

kiedy spróbuję: $ ip = $ _SERVER ["REMOTE_ADDR"]; echo $ ip; zwraca to: 10.48.44.43, czy wiesz na czym polega problem? Użyłem alspo maxmind geoip, a kiedy użyłem geoip_country_name_by_addr ($ gi, $ ip) ponownie nie zwróciło mi nic ...
mOna

@mOna, zwraca twój adres IP. Aby uzyskać więcej informacji, prosimy o udostępnienie kodu.
Ram Sharma,

Odkryłem, że problem dotyczy mojego adresu IP, ponieważ dotyczy on sieci prywatnej. następnie podałem swój prawdziwy adres IP w ifconfig i użyłem go w moim programie. to zadziałało :) Moje pytanie brzmi: jak uzyskać prawdziwe IP w przypadku użytkowników podobnych do mnie? (jeśli używają lokalnego
adresu

9

Wypróbuj ten prosty kod jednoliniowy, a ze zdalnego adresu IP otrzymasz kraj i miasto odwiedzających.

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

9

Możesz użyć usługi internetowej z http://ip-api.com
w kodzie php, wykonaj następujące czynności:

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

zapytanie zawiera wiele innych informacji:

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',
)

Używane ip-api.com, ponieważ podają również nazwę dostawcy usług internetowych!
Richard Tinkler,

1
Użyłem, ponieważ dostarczają również strefę czasową
Roy Shoa,

8

Istnieje dobrze utrzymana wersja pliku bazy danych kraju ip-> utrzymywana przez społeczność Perl w CPAN

Dostęp do tych plików nie wymaga serwera danych, a same dane to około 515 tys

Higemaru napisał opakowanie PHP, aby porozmawiać z tymi danymi: php-ip-country-fast


6

Wiele różnych sposobów, aby to zrobić ...

Rozwiązanie nr 1:

Jedną z usług zewnętrznych, z których możesz skorzystać, jest http://ipinfodb.com . Zapewniają nazwę hosta, geolokalizację i dodatkowe informacje.

Zarejestruj się, aby uzyskać klucz API tutaj: http://ipinfodb.com/register.php . Umożliwi to pobieranie wyników z ich serwera, bez tego nie będzie działać.

Skopiuj i wklej następujący kod 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'];

Minusem:

Cytowanie z ich strony internetowej:

Nasz bezpłatny interfejs API korzysta z wersji IP2Location Lite, która zapewnia niższą dokładność.

Rozwiązanie nr 2:

Ta funkcja zwróci nazwę kraju za pomocą usługi 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));

Wynik:

Array ( [country] => DE - Germany )  // Full Country Name

3
Cytując z ich strony internetowej: „Jesteś ograniczony do 1000 żądań API dziennie. Jeśli potrzebujesz więcej żądań lub potrzebujesz wsparcia SSL, zobacz nasze płatne plany”.
Walter Tross,

Użyłem go na mojej osobistej stronie internetowej, dlatego go opublikowałem. Dziękuję za informację ... nie zdawałem sobie z tego sprawy.
Włożyłem

@imbondbaby: Cześć, próbowałem twojego kodu, ale dla mnie zwraca to: Array ([country] => -), nie rozumiem problemu, ponieważ kiedy próbuję to wydrukować: $ ipaddress = $ _SERVER ['REMOTE_ADDR' ]; pokazuje mi ten ip: 10.48.44.43, nie rozumiem, dlaczego ten ip nie działa! Mam na myśli to, że gdziekolwiek wstawię ten numer, nie zwróci on żadnego kraju !!! counld u plz pomóż mi?
mOna

5

Moja usługa ipdata.co udostępnia nazwę kraju w 5 językach! Podobnie jak organizacja, waluta, strefa czasowa, kod telefoniczny, flaga, dane operatora komórkowego, dane proxy i dane statusu węzła Tor Exit z dowolnego adresu IPv4 lub IPv6.

Ta odpowiedź wykorzystuje „testowy” klucz API, który jest bardzo ograniczony i przeznaczony tylko do testowania kilku połączeń. Zarejestruj swój bezpłatny klucz API i codziennie otrzymuj do 1500 wniosków o programowanie.

Jest również niezwykle skalowalny, z 10 regionami na całym świecie, z których każdy jest w stanie obsłużyć> 10 000 żądań na sekundę!

Dostępne opcje obejmują; Angielski (en), niemiecki (de), japoński (ja), francuski (fr) i chiński uproszczony (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;
//美国

1
Niech Bóg cię błogosławi, człowieku! Dostałem więcej niż to, o co prosiłem! Szybkie pytanie: czy mogę go użyć do prod? To znaczy, nie zamierzasz tego odłożyć w najbliższym czasie, prawda?
Powiedział

1
Wcale nie :) W rzeczywistości dodaję więcej regionów i bardziej polski. Cieszę się, że okazało się to pomocne :)
Jonathan

Bardzo pomocny, szczególnie z dodatkowymi parametrami, rozwiązał dla mnie więcej niż jeden problem!
Powiedział

3
Dziękuję za pozytywny odzew! Zbudowałem wokół najpopularniejszych przypadków użycia takiego narzędzia, celem było wyeliminowanie konieczności dodatkowego przetwarzania po geolokalizacji, cieszę się, że to się opłaca dla użytkowników
Jonathan

4

Nie jestem pewien, czy jest to nowa usługa, ale teraz (2016) najłatwiejszym sposobem w php jest skorzystanie z usługi internetowej php geoplugina: http://www.geoplugin.net/php.gp :

Podstawowe użycie:

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

Zapewniają również gotową klasę: http://www.geoplugin.com/_media/webservices/geoplugin.class.php.tgz?id=webservices%3Aphp&cache=cache


Użyłeś elsepo, elsektóry powoduje błąd. Co próbowałeś zapobiec? REMOTE_ADDR powinien być dostępny cały czas?
AlexioVay

@Vaia - Być może powinno być, ale nigdy nie wiadomo.
billynoah

Czy znasz przypadek, w którym nie jest dostępny?
AlexioVay,

2
@Vaia - z dokumentów PHP na temat $_SERVER: „Nie ma gwarancji, że każdy serwer sieciowy zapewni którykolwiek z nich; serwery mogą pominąć niektóre lub udostępnić inne, które nie zostały tutaj wymienione”.
billynoah

1
Uwaga: istnieje limit żądań; z ich strony: „Jeśli geoplugin.net zareagował doskonale, to zatrzymał się, to przekroczyłeś limit bezpłatnego wyszukiwania wynoszący 120 żądań na minutę.”
Rick Hellewell

2

ja używam ipinfodb.com interfejsu API i otrzymuję dokładnie to, czego szukasz.

Jest całkowicie darmowy, wystarczy się zarejestrować, aby otrzymać klucz API. Możesz dołączyć ich klasę php, pobierając ze strony internetowej lub możesz użyć formatu adresu URL, aby pobrać informacje.

Oto co robię:

Włączyłem ich klasę php do mojego skryptu i używając poniższego kodu:

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

Otóż ​​to.


2

możesz użyć http://ipinfo.io/, aby uzyskać szczegółowe informacje na temat adresu IP Jest łatwy w użyciu.

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

    ?>

2

Zastąp 127.0.0.1odwiedzającymi adres IP.

$country = geoip_country_name_by_name('127.0.0.1');

Instrukcje instalacji są tutaj i przeczytaj to, aby dowiedzieć się, jak uzyskać miasto, stan, kraj, długość geograficzną, szerokość geograficzną itp.


Podaj więcej rzeczywistego kodu niż tylko twarde linki.
Bram Vanroy

Późniejsze wiadomości z linku: „Z dniem 2 stycznia 2019 r. Maxmind wycofał oryginalne bazy danych GeoLite, których używaliśmy we wszystkich tych przykładach. Możesz przeczytać pełne ogłoszenie tutaj: support.maxmind.com/geolite-legacy-discontinuation-notice
Rick Hellewell,


2

Mam krótką odpowiedź, której użyłem w projekcie. W mojej odpowiedzi uważam, że masz adres IP użytkownika.

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

1

Wiem, że to stare, ale wypróbowałem tutaj kilka innych rozwiązań, które wydają się być nieaktualne lub po prostu zwracają wartość zerową. Więc tak to zrobiłem.

Korzystanie, http://www.geoplugin.net/json.gp?ip=które nie wymaga żadnego rodzaju rejestracji ani płacenia za usługę.

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

A jeśli potrzebujesz dodatkowych informacji na ten temat, jest to pełny zwrot Jsona:

{
  "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
}

1

Napisałem klasę na podstawie odpowiedzi „Chandra Nakka”. Mamy nadzieję, że może to pomóc ludziom w zapisywaniu informacji z geoplugin do sesji, dzięki czemu ładowanie jest znacznie szybsze przy odtwarzaniu informacji. Zapisuje również wartości w prywatnej tablicy, więc przywołanie tego samego kodu jest najszybsze, jak mogłoby być.

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

Odpowiadając na pytanie „op” w tej klasie możesz zadzwonić

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

Pozostałe dostępne właściwości to:

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

Powracający

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) "£"

0

Użytkownik Kraj API ma dokładnie to, czego potrzebujesz. Oto przykładowy kod używający file_get_contents () tak jak pierwotnie:

$result = json_decode(file_get_contents('http://usercountry.com/v1.0/json/'.$cip), true);
$result['country']['name']; // this contains what you need

1
Ten interfejs API umożliwia 100 (bezpłatnych) połączeń API dziennie.
zreformowany

0

Możesz uzyskać odwiedzających kraj i miasto za pomocą interfejsu API ipstack geo. Musisz uzyskać własny interfejs API ipstack, a następnie użyć kodu poniżej:

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

Źródło: Uzyskaj odwiedzających kraj i miasto w PHP za pomocą interfejsu API ipstack


0

To tylko uwaga dotycząca bezpieczeństwa,get_client_ip() że większość odpowiedzi tutaj została uwzględniona w głównej funkcji get_geo_info_for_this_ip().

Nie polegaj zbytnio na danych IP w nagłówkach żądania, takich jak Client-IPlub, X-Forwarded-Forponieważ mogą one być bardzo łatwo sfałszowane, jednak powinieneś polegać na źródłowym adresie IP połączenia TCP, który jest faktycznie ustanowiony między naszym serwerem a klientem, $_SERVER['REMOTE_ADDR']ponieważ może ” sfałszowane

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

Można podać kraj fałszywego adresu IP, ale należy pamiętać, że użycie tego adresu IP w dowolnym modelu bezpieczeństwa (np. Zakazanie adresu IP wysyłającego częste żądania) zniszczy cały model bezpieczeństwa. IMHO Wolę używać rzeczywistego adresu IP klienta, nawet jeśli jest to adres IP serwera proxy.


0

Próbować

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

  ?>

Część if-else da ci adres IP odwiedzającego, a następna część zwróci kod kraju. Spróbuj odwiedzić api.wipmania.com, a następnie api.wipmania.com/[twoj_IP_adres]
Dipanshu Mahla

0

Możesz skorzystać z mojej usługi: https://SmartIP.io , która zapewnia pełne nazwy krajów i nazwy miast dla dowolnego adresu IP. Udostępniamy także strefy czasowe, waluty, wykrywanie proxy, wykrywanie węzłów TOR i wykrywanie kryptograficzne.

Wystarczy się zarejestrować i otrzymać bezpłatny klucz API, który pozwala na 250 000 żądań miesięcznie.

Przy użyciu oficjalnej biblioteki PHP wywołanie API staje się:

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

Sprawdź dokumentację API, aby uzyskać więcej informacji: https://smartip.io/docs


0

Od 2019 r. DB kraju MaxMind można używać w następujący sposób:

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

Źródło: https://github.com/maxmind/MaxMind-DB-Reader-php


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.