Bắt quốc gia của khách truy cập từ IP của họ


220

Tôi muốn có được quốc gia của khách truy cập thông qua IP của họ ... Ngay bây giờ tôi đang sử dụng cái này ( http://api.hostip.info/country.php?ip= ......)

Đây là mã của tôi:

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

?>

Chà, nó hoạt động tốt, nhưng điều này là, điều này trả về mã quốc gia như Hoa Kỳ hoặc CA., chứ không phải toàn bộ tên quốc gia như Hoa Kỳ hoặc Canada.

Vì vậy, có bất kỳ thay thế tốt cho hostip.info cung cấp này?

Tôi biết rằng tôi chỉ có thể viết một số mã mà cuối cùng sẽ biến hai chữ cái này thành tên quốc gia, nhưng tôi quá lười để viết một mã chứa tất cả các quốc gia ...

PS: Vì một số lý do, tôi không muốn sử dụng bất kỳ tệp CSV đã tạo sẵn nào hoặc bất kỳ mã nào sẽ lấy thông tin này cho tôi, đại loại như mã sẵn sàng ip2country và CSV.


20
Đừng lười biếng, không có nhiều quốc gia, và không quá khó để có được một bảng dịch cho mã chữ cái 2 cho tên quốc gia.
Chris Henry

Sử dụng tính năng địa lý Maxmind. Nó sẽ bao gồm tên quốc gia trong kết quả. maxmind.com/app/php
Tchoupi

Nhiệm vụ đầu tiên của bạn $real_ip_addressluôn bị bỏ qua. Dù sao, hãy nhớ rằng X-Forwarded-Fortiêu đề HTTP có thể cực kỳ dễ bị làm giả và có những proxy như www.hidemyass.com
Walter Tross

5
IPLocate.io cung cấp API miễn phí: https://www.iplocate.io/api/lookup/8.8.8.8- Tuyên bố miễn trừ trách nhiệm: Tôi chạy dịch vụ này.
ttarik

Tôi khuyên bạn nên dùng thử Ipregology : api.ipregistry.co/ (từ chối trách nhiệm: Tôi điều hành dịch vụ).
Laurent

Câu trả lời:


495

Hãy thử chức năng PHP đơn giản này.

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

?>

Cách sử dụng:

Ví dụ1: Nhận chi tiết địa chỉ IP của khách truy cập

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

?>

Ví dụ 2: Nhận chi tiết về bất kỳ địa chỉ IP nào. [Hỗ trợ 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 )

?>

1
Tại sao tôi nhận được unkn tất cả thời gian với mỗi ip? , được sử dụng cùng mã.
echo_Me

1
Bạn nhận được "Không xác định" có thể vì máy chủ của bạn không cho phép file_get_contents(). Chỉ cần kiểm tra tệp error_log của bạn. Cách giải quyết: xem câu trả lời của tôi.
Kai Noack

3
cũng có thể là do bạn kiểm tra cục bộ (192.168.1.1 / 127.0.0.1 / 10.0.0.1)
Hontoni

1
Nhớ lưu trữ kết quả trong một khoảng thời gian xác định. Ngoài ra, như một lưu ý, bạn không bao giờ nên dựa vào một trang web khác để lấy bất kỳ dữ liệu nào, trang web có thể ngừng hoạt động, dịch vụ có thể dừng lại, v.v. Và nếu bạn tăng số lượng khách truy cập trên trang web của mình, dịch vụ này có thể cấm bạn.
máy móc

1
Thực hiện theo: đây là một vấn đề khi kiểm tra một trang web trên localhost. Bất kỳ cách để sửa chữa cho mục đích thử nghiệm? Sử dụng IP localhost tiêu chuẩn 127.0.0.1
Nick

54

Bạn có thể sử dụng API đơn giản từ 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>";

Chức năng sử dụng

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

Đầu ra

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

Nó làm cho bạn có rất nhiều lựa chọn bạn có thể chơi xung quanh

Cảm ơn

:)


1
Điều đó thật tuyệt. Nhưng trong khi thử nghiệm ở đây không có giá trị nào trong các trường sau "geoplugin_city, geoplugin_region, geoplugin_regionCode, geoplugin_regionName" .. Lý do là gì? Có giải pháp nào không? Cảm ơn trước
WebDevRon

31

Tôi đã thử câu trả lời của Chandra nhưng cấu hình máy chủ của tôi không cho phép file_get_contents ()

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

Tôi đã sửa đổi mã của Chandra để nó cũng hoạt động cho các máy chủ như thế bằng cách sử dụng 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

?>

Hy vọng rằng sẽ giúp ;-)


1
Theo các tài liệu trên trang của họ: "Nếu geoplugin.net phản hồi hoàn hảo, sau đó dừng lại, thì bạn đã vượt quá giới hạn tra cứu miễn phí 120 yêu cầu mỗi phút."
Rick Hellewell

Làm việc rất đẹp. Cảm ơn!
Najeeb


11

Sử dụng MaxMind GeoIP (hoặc GeoIPLite nếu bạn chưa sẵn sàng trả tiền).

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

@Joyce: Tôi đã thử sử dụng Maxmind API và DB, nhưng tôi không biết tại sao nó không hoạt động với tôi, thực ra nó hoạt động chung, nhưng ví dụ như khi tôi chạy $ _SERVER ['REMOTE_ADDR']; nó hiển thị cho tôi ip này: 10,48.44.43, nhưng khi tôi sử dụng nó trong Geoip_country_code_by_addr ($ gi, $ ip), nó có trả về gì không, có ý kiến ​​gì không?
mOna

Đó là một địa chỉ IP dành riêng (địa chỉ IP nội bộ từ mạng cục bộ của bạn). Hãy thử chạy mã trên một máy chủ từ xa.
Joyce Babu


10

Hãy xem php-ip-2-country từ code.google. Cơ sở dữ liệu họ cung cấp được cập nhật hàng ngày, do đó không cần kết nối với máy chủ bên ngoài để kiểm tra nếu bạn lưu trữ máy chủ SQL của riêng bạn. Vì vậy, sử dụng mã bạn sẽ chỉ phải gõ:

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

Mã ví dụ (từ tài nguyên)

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

Đầu ra

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
chúng ta phải cung cấp thông tin cơ sở dữ liệu để làm việc? có vẻ không tốt
echo_Me

10

Chúng tôi có thể sử dụng geobytes.com để lấy vị trí bằng địa chỉ IP của người dùng

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

nó sẽ trả về dữ liệu như thế này

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
)

Chức năng lấy IP người dùng

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

Tôi đã thử mã của bạn, nó trả về mã này cho tôi: Mảng ([đã biết] => sai)
mOna

khi tôi thử điều này: $ ip = $ _SERVER ["REMOTE_ADDR"]; tiếng vang $ ip; nó trả về nó: 10,48,44,43, bạn có biết vấn đề là gì không ?? Tôi đã sử dụng alspo maxmind Geoip và khi tôi sử dụng Geoip_country_name_by_addr ($ gi, $ ip) một lần nữa, tôi không trả lại cho tôi điều gì ...
mOna

@mOna, nó trả về địa chỉ IP của bạn. để biết thêm chi tiết xin vui lòng, chia sẻ mã của bạn.
Ram Sharma

Tôi thấy rằng vấn đề được thực hiện với ip của tôi vì nó là cho mạng riêng. sau đó tôi sử dụng ip thật của mình trong ifconfig và sử dụng nó trong chương trình của mình. Sau đó, nó hoạt động :) Bây giờ, câu hỏi của tôi là làm thế nào để có được ip thực sự trong trường hợp những người dùng tương tự như tôi? (nếu họ sử dụng ip địa phương) .. Tôi đã viết mã của tôi ở đây: stackoverflow.com/questions/25958564/...
Mona

9

Hãy thử mã một dòng đơn giản này, Bạn sẽ nhận được quốc gia và thành phố của khách truy cập từ địa chỉ từ xa ip của họ.

$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

Bạn có thể sử dụng dịch vụ web từ http://ip-api.com
trong mã php của mình, thực hiện như sau:

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

truy vấn có nhiều thông tin khác:

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

Được sử dụng ip-api.com vì họ cũng cung cấp tên ISP!
Richard Tinkler

1
Tôi đã sử dụng vì họ cũng cung cấp Múi giờ
Roy Shoa

8

Có một phiên bản tệp phẳng được duy trì tốt của cơ sở dữ liệu ip-> quốc gia được duy trì bởi cộng đồng Perl tại CPAN

Truy cập vào các tệp đó không yêu cầu bộ dữ liệu và bản thân dữ liệu là khoảng 515k

Higemaru đã viết một trình bao bọc PHP để nói chuyện với dữ liệu đó: php-ip-country-fast


6

Nhiều cách khác nhau để làm điều đó ...

Giải pháp số 1:

Một dịch vụ bên thứ ba bạn có thể sử dụng là http://ipinfodb.com . Họ cung cấp tên máy chủ, định vị địa lý và thông tin bổ sung.

Đăng ký khóa API tại đây: http://ipinfodb.com/register.php . Điều này sẽ cho phép bạn lấy kết quả từ máy chủ của họ, nếu không có nó thì nó sẽ không hoạt động.

Sao chép và qua mã PHP sau:

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

Nhược điểm:

Trích dẫn từ trang web của họ:

API miễn phí của chúng tôi đang sử dụng phiên bản IP2Location Lite cung cấp độ chính xác thấp hơn.

Giải pháp số 2:

Hàm này sẽ trả về tên quốc gia bằng cách sử dụng dịch vụ 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));

Đầu ra:

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

3
Trích dẫn từ trang web của họ: "Bạn bị giới hạn ở 1.000 yêu cầu API mỗi ngày. Nếu bạn cần thực hiện thêm yêu cầu hoặc cần hỗ trợ SSL, hãy xem các gói trả phí của chúng tôi."
Walter Tross

Tôi đã sử dụng nó trên trang web cá nhân của tôi vì vậy đó là lý do tại sao tôi đăng nó. Cảm ơn bạn đã thông tin ... đã không nhận ra nó. Tôi đã nỗ lực nhiều hơn cho bài viết, vì vậy vui lòng xem bài đăng được cập nhật :)
imbondbaby

@imbondbaby: Xin chào, tôi đã thử mã của bạn, nhưng đối với tôi, nó trả về cái này: Array ([country] => -), tôi không hiểu vấn đề kể từ khi tôi thử in cái này: $ ipaddress = $ _SERVER ['REMOTE_ADDR' ]; nó cho tôi thấy ip này: 10,48.44.43, tôi không thể hiểu tại sao ip này không hoạt động! Ý tôi là bất cứ nơi nào tôi chèn số này, nó sẽ không trả về bất kỳ quốc gia nào !!! Counld u plz giúp tôi?
mOna

5

Dịch vụ ipdata.co của tôi cung cấp tên quốc gia bằng 5 ngôn ngữ! Cũng như tổ chức, tiền tệ, múi giờ, mã gọi, cờ, dữ liệu Nhà cung cấp dịch vụ di động, dữ liệu Proxy và dữ liệu trạng thái Tor Thoát Node từ bất kỳ địa chỉ IPv4 hoặc IPv6 nào.

Câu trả lời này sử dụng Khóa API 'kiểm tra' rất hạn chế và chỉ có nghĩa là để thử nghiệm một vài cuộc gọi. Đăng ký Khóa API miễn phí của riêng bạn và nhận tới 1500 yêu cầu hàng ngày để phát triển.

Nó cũng cực kỳ có thể mở rộng với 10 vùng trên toàn thế giới, mỗi vùng có thể xử lý> 10.000 yêu cầu mỗi giây!

Các tùy chọn bao gồm; Tiếng Anh (en), tiếng Đức (de), tiếng Nhật (ja), tiếng Pháp (fr) và tiếng Trung giản thể (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
Chúa phù hộ bạn, người đàn ông! Tôi đã nhận được nhiều hơn những gì tôi yêu cầu! Câu hỏi nhanh: tôi có thể sử dụng nó cho prod không? Ý tôi là, bạn sẽ không đặt nó xuống bất cứ lúc nào sớm, phải không?
Nói

1
Hoàn toàn không :) Tôi thực tế là thêm nhiều vùng hơn và đánh bóng hơn. Vui mừng bạn tìm thấy điều này để được giúp đỡ :)
Jonathan

Rất hữu ích, đặc biệt với các thông số bổ sung, đã giải quyết nhiều hơn một vấn đề cho tôi!
Nói

3
Cảm ơn các ý kiến ​​phản hồi tích cực! Tôi đã xây dựng xung quanh các usecase phổ biến nhất cho một công cụ như vậy, mục tiêu là loại bỏ việc phải xử lý thêm sau khi định vị địa lý, rất vui khi thấy điều này được đền đáp cho người dùng
Jonathan

4

Không chắc đây có phải là dịch vụ mới không nhưng bây giờ (2016) cách dễ nhất trong php là sử dụng dịch vụ web php của geoplugin: http://www.geoplugin.net/php.gp :

Cách sử dụng cơ bản:

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

Họ cũng cung cấp một lớp được xây dựng sẵn sàng: http://www.geoplugin.com/_media/webservice/geoplugin. Class.php.tgz?id=webservice%3Aphp&cache=cache


Bạn đã sử dụng elsesau elseđó gây ra lỗi. Bạn đã cố gắng ngăn chặn điều gì? REMOTE_ADDR nên có sẵn mọi lúc?
AlexioVay

@Vaia - Có lẽ nó nên nhưng bạn không bao giờ biết.
billynoah

Có một trường hợp mà nó không có sẵn mà bạn biết?
AlexioVay

2
@Vaia - từ các tài liệu PHP trên $_SERVER: "Không có gì đảm bảo rằng mọi máy chủ web sẽ cung cấp bất kỳ thứ nào trong số này; các máy chủ có thể bỏ qua một số hoặc cung cấp các tài liệu khác không được liệt kê ở đây."
billynoah

1
Lưu ý có giới hạn cho các yêu cầu; từ trang web của họ: "Nếu geoplugin.net phản hồi hoàn hảo, sau đó dừng lại, thì bạn đã vượt quá giới hạn tra cứu miễn phí 120 yêu cầu mỗi phút."
Rick Hellewell

2

tôi đang dùng ipinfodb.com api và nhận được chính xác những gì bạn đang tìm kiếm.

Nó hoàn toàn miễn phí, bạn chỉ cần đăng ký với họ để lấy chìa khóa api của bạn. Bạn có thể bao gồm lớp php của họ bằng cách tải xuống từ trang web của họ hoặc bạn có thể sử dụng định dạng url để truy xuất thông tin.

Đây là những gì tôi đang làm:

Tôi đã bao gồm lớp php của họ trong tập lệnh của mình và sử dụng đoạn mã dưới đây:

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

Đó là nó.


2

bạn có thể sử dụng http://ipinfo.io/ để biết chi tiết về địa chỉ IP Thật dễ sử dụng.

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

Thay thế 127.0.0.1bằng khách truy cập IpAddress.

$country = geoip_country_name_by_name('127.0.0.1');

Hướng dẫn cài đặt có tại đâyđọc phần này để biết cách lấy Thành phố, Bang, Quốc gia, Kinh độ, Vĩ độ, v.v ...


Vui lòng cung cấp nhiều mã thực tế hơn là chỉ liên kết cứng.
Bram Vanroy

Tin tức sau đó từ liên kết: "Kể từ ngày 2 tháng 1 năm 2019, Maxmind đã ngừng cơ sở dữ liệu GeoLite ban đầu mà chúng tôi đã sử dụng trong tất cả các ví dụ này. Bạn có thể đọc thông báo đầy đủ tại đây: support.maxmind.com/geolite-legacy-discContinating-notice "
Rick Hellewell


2

Tôi có một câu trả lời ngắn mà tôi đã sử dụng trong một dự án. Trong câu trả lời của tôi, tôi cho rằng bạn có địa chỉ IP của khách truy cập.

$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

Tôi biết điều này đã cũ, nhưng tôi đã thử một vài giải pháp khác ở đây và chúng dường như đã lỗi thời hoặc chỉ trả về null. Vì vậy, đây là cách tôi đã làm nó.

Sử dụng http://www.geoplugin.net/json.gp?ip=mà không yêu cầu bất kỳ loại đăng ký hoặc trả tiền cho dịch vụ.

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

Và nếu bạn muốn biết thêm thông tin về nó, đây là sự trở lại đầy đủ của 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
}

1

Tôi đã viết một lớp học dựa trên câu trả lời "Chandra Nakka". Hy vọng rằng nó có thể giúp mọi người thoát nó lưu thông tin từ geoplugin vào một phiên để tải nhanh hơn nhiều khi nhớ lại thông tin. Nó cũng lưu các giá trị vào một mảng riêng để việc gọi lại trong cùng một mã là nhanh nhất có thể.

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

Trả lời câu hỏi 'op' với lớp này, bạn có thể gọi

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

Và các thuộc tính khác có sẵn là:

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

Trở về

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

Các API tài Nước có chính xác những gì bạn cần. Đây là mã mẫu sử dụng file_get_contents () như ban đầu bạn làm:

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

1
API này cho phép 100 cuộc gọi API (miễn phí) mỗi ngày.
cải cách

0

Bạn có thể nhận được khách truy cập quốc gia và thành phố bằng API địa lý ipstack. Bạn cần có API ipstack của riêng mình và sau đó sử dụng mã dưới đây:

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

Nguồn: Nhận khách truy cập quốc gia và thành phố bằng PHP bằng ipstack API


0

Đây chỉ là một lưu ý bảo mật về chức năng của get_client_ip()hầu hết các câu trả lời ở đây đã được đưa vào bên trong chức năng chính củaget_geo_info_for_this_ip() .

Đừng phụ thuộc quá nhiều vào dữ liệu IP trong các tiêu đề yêu cầu Client-IPhoặc X-Forwarded-Forbởi vì chúng có thể bị giả mạo rất dễ dàng, tuy nhiên bạn nên dựa vào IP nguồn của kết nối TCP thực sự được thiết lập giữa máy chủ của chúng tôi và máy khách$_SERVER['REMOTE_ADDR']nó có thể ' bị giả mạo

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

Bạn có thể lấy quốc gia của IP giả mạo nhưng hãy nhớ rằng sử dụng IP này trong bất kỳ mô hình bảo mật nào (ví dụ: cấm IP gửi yêu cầu thường xuyên) sẽ phá hủy toàn bộ mô hình bảo mật. IMHO Tôi thích sử dụng IP máy khách thực tế ngay cả khi đó là IP của máy chủ proxy.


0

Thử

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

  ?>

Phần if-other sẽ cung cấp cho bạn địa chỉ IP của khách truy cập và phần tiếp theo sẽ trả về mã quốc gia. Hãy thử truy cập api.wipmania.com và sau đó api.wipmania.com/[your_IP_address]
Dipanshu Mahla

0

Bạn có thể sử dụng dịch vụ của tôi: https://SmartIP.io , nơi cung cấp tên quốc gia đầy đủ và tên thành phố của bất kỳ địa chỉ IP nào. Chúng tôi cũng tiết lộ múi giờ, tiền tệ, phát hiện proxy, phát hiện nút TOR và phát hiện tiền điện tử.

Bạn chỉ cần đăng ký và nhận khóa API miễn phí cho phép 250.000 yêu cầu mỗi tháng.

Sử dụng thư viện PHP chính thức, lệnh gọi API trở thành:

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

Kiểm tra tài liệu API để biết thêm thông tin: https://smartip.io/docs


0

Kể từ năm 2019, DB quốc gia MaxMind có thể được sử dụng như sau:

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

Nguồn: https://github.com/maxmind/MaxMind-DB-Reader-php


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.