从IP获取访问者国家


220

我想通过他们的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可以提供这种方法吗?

我知道我可以编写一些代码,最终将这两个字母转换为整个国家/地区名称,但是我懒得编写包含所有国家/地区的代码...

PS:出于某种原因,我不想使用任何现成的CSV文件或任何可以为我获取此信息的代码,例如ip2country现成的代码和CSV。


20
别偷懒,没有那么多国家,而且要获取FIPS 2字母代码到国家名称的转换表也并不难。
克里斯·亨利

使用Maxmind geoip功能。结果中将包含国家名称。maxmind.com/app/php
Tchoupi 2012年

您对的第一次分配$real_ip_address始终会被忽略。无论如何,请记住X-Forwarded-ForHTTP标头可以非常容易地被伪造,并且存在诸如www.hidemyass.com的代理
Walter Tross 2014年

5
IPLocate.io提供了免费的API:https://www.iplocate.io/api/lookup/8.8.8.8-免责声明:我运行此服务。
ttarik '17

我建议尝试尝试Ipregistryapi.ipregistry.co/… (免责声明:我运行该服务)。
洛朗

Answers:


495

试试这个简单的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 )

?>

1
为什么每个IP都会一直不知所措?,使用相同的代码。
echo_Me 2014年

1
您得到“未知”的原因可能是服务器不允许file_get_contents()。只需检查您的error_log文件。解决方法:请参阅我的答案。
Kai Noack

3
这也可能是因为u检查本地语言(192.168.1.1 / 127.0.0.1 / 10.0.0.1)
洪通尼2014年

1
请记住将结果缓存一定的时间。另外,请注意,您永远不要依赖其他网站来获取任何数据,该网站可能会关闭,该服务可能会停止,等等。而且,如果网站上访问者的数量增加,则该服务可能会禁止您访问。
machineaddict

1
继续:在localhost上测试站点时,这是一个问题。有什么方法可以修复以进行测试吗?使用标准的127.0.0.1本地主机IP
Nick

54

您可以从http://www.geoplugin.net/使用简单的API

$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

它使您可以选择多种选择

谢谢

:)


1
太棒了。但是,在此处进行测试时,以下字段“ geoplugin_city,geoplugin_region,geoplugin_regionCode,geoplugin_regionName”中没有任何值。原因是什么?有什么解决办法吗?在此先感谢
WebDevRon 2015年

31

我尝试了Chandra的答案,但是我的服务器配置不允许file_get_contents()

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

我修改了Chandra的代码,以便它也可以使用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

?>

希望能有所帮助;-)


1
根据他们网站上的文档:“如果geoplugin.net响应完美,然后停止了,那么您已经超过了每分钟120个请求的免费查找限制。”
Rick Hellewell

做工精美。谢谢!
纳耶布(Najeeb)


11

使用MaxMind GeoIP(如果尚未准备付款,则使用GeoIPLite)。

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

@Joyce:我尝试使用Maxmind API和DB,但是我不知道为什么它对我不起作用,实际上它通常可以工作,但是例如当我运行此$ _SERVER ['REMOTE_ADDR'];它向我显示此ip:10.48.44.43,但是当我在geoip_country_code_by_addr($ gi,$ ip)中使用它时,它什么也不返回,有什么想法吗?
mOna 2014年

这是一个保留的IP地址(您本地网络中的内部IP地址)。尝试在远程服务器上运行代码。
Joyce Babu 2014年


10

从code.google 查看php-ip-2-country。他们提供的数据库每天更新一次,因此如果您托管自己的SQL Server,则无需连接到外部服务器进行检查。因此,使用代码只需键入:

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

4
我们必须提供数据库信息才能工作吗?好像不好
echo_Me 2014年

10

我们可以使用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;
}

我尝试了您的代码,它为我返回了这个信息:Array([known] => false)
mOna 2014年

当我尝试这样做时:$ ip = $ _SERVER [“ REMOTE_ADDR”]; echo $ ip; 它返回它:10.48.44.43,你知道是什么问题吗?我使用了alspo maxmind geoip,当我使用geoip_country_name_by_addr($ gi,$ ip)时,它什么也没有返回……
mOna 2014年

@mOna,它返回您的IP地址。有关更多详细信息,请共享您的代码。
Ram Sharma 2014年

我发现问题已经解决了,因为它是针对专用网络的。然后我在ifconfig中输入了真正的IP,并在程序中使用了它。然后它起作用了:)现在,我的问题是,在那些与我相似的用户的情况下,如何获得真实的ip?(如果他们使用本地IP)..我写到这里我的代码:stackoverflow.com/questions/25958564/...
MONA

9

试试这个简单的单行代码,您将从其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'];

9

您可以 在php代码中使用来自http://ip-api.com的Web服务
,方法如下:

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

使用ip-api.com,因为它们还提供ISP名称!
理查德·廷克勒

1
我之所以使用,是因为它们还提供了时区
Roy Shoa

8

CPAN的Perl社区维护着ip-> country数据库的维护良好的平面文件版本

访问这些文件不需要数据服务器,数据本身大约为515k

Higemaru编写了一个PHP包装程序来与该数据对话:php-ip-country-fast


6

许多不同的方式来做...

解决方案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

3
在他们的网站上报价:“每天最多只能有1,000个API请求。如果您需要发出更多请求或需要SSL支持,请参阅我们的付费计划。”
Walter Tross 2014年

我在个人网站上使用了它,所以才发布了它。感谢您提供的信息...没有意识到。我在帖子上投入了更多精力,所以请查看更新的帖子:)
imbondbaby 2014年

@imbondbaby:嗨,我尝试了您的代码,但对我来说,它返回了这个:Array([country] =>--),我不明白这个问题,因为当我尝试打印此代码时:$ ipaddress = $ _SERVER ['REMOTE_ADDR' ]; 它向我显示此IP:10.48.44.43,我不明白为什么该IP无法正常工作!我的意思是,无论我在哪里插入此号码,都不会返回任何国家/地区!您可以帮我吗?
mOna 2014年

5

我的服务ipdata.co提供5种语言的国家/地区名称!以及来自任何IPv4或IPv6地址的组织,货币,时区,呼叫代码,标志,移动运营商数据,代理数据和Tor出口节点状态数据。

此答案使用的“测试” 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;
//美国

1
上帝保佑你,伙计!我得到的比我想要的要多!快速提问:我可以将其用于产品吗?我的意思是,您不会很快放下它,是吗?
赛义德

1
一点也不:)实际上,我正在添加更多区域和更多波兰语。很高兴您发现这对您有所帮助:)
Jonathan

非常有帮助,特别是在附加参数方面,对我来说解决了多个问题!
赛义德

3
感谢您的积极反馈!我围绕此类工具的最常见用例进行了构建,目标是消除在地理位置定位后无需进行任何其他处理的过程,很高兴看到这能为用户带来回报
Jonathan

4

不确定这是否是一项新服务,但是现在(2016年),php中最简单的方法是使用geoplugin的php Web服务: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


您使用了elseafter之后else会导致错误。您试图防止什么?REMOTE_ADDR应该一直可用吗?
AlexioVay

@Vaia-也许应该,但是你永远不知道。
billynoah

有没有您不知道的情况?
AlexioVay

2
@Vaia-来自PHP文档,网址为$_SERVER“不能保证每个Web服务器都会提供其中任何一个;服务器可能会省略其中的一些,或者提供此处未列出的其他服务器。”
billynoah

1
注意请求是有限制的。来自他们的网站:“如果geoplugin.net响应完美,然后停止,则您已经超过了每分钟120个请求的免费查找限制。”
Rick Hellewell

2

我在用 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'];

而已。


2

您可以使用 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; /

    ?>

2

替换127.0.0.1为访问者IpAddress。

$country = geoip_country_name_by_name('127.0.0.1');

安装说明在此处,并阅读此内容以了解如何获取城市,州,国家/地区,经度,纬度等。


除了提供硬链接之外,请提供更多实际代码。
布拉姆·范罗伊

链接的最新消息:“自2019年1月2日起,Maxmind终止了我们在所有这些示例中一直使用的原始GeoLite数据库。您可以在此处阅读完整的公告:support.maxmind.com/geolite-legacy-discontinuation-notice
Rick Hellewell,


2

我在一个项目中使用了一个简短的答案。在我的回答中,我认为您具有访客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;
}

1

我知道这很旧,但是我在这里尝试了其他一些解决方案,它们似乎已经过时或只是返回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
}

1

我写了一个基于“钱德拉·纳卡”答案的课程。希望它可以帮助人们将信息从geoplugin保存到会话中,以便在调用信息时加快加载速度。它还将这些值保存到私有数组中,因此在相同的代码中进行调用是最快的。

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

0

用户国家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

1
该API每天允许100次(免费)API调用。
改良

0

您可以使用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 ."";
?>

资料来源:使用ipstack API用PHP获取访客所在的国家和城市


0

这只是关于功能的安全说明get_client_ip()此处的大多数答案已包含在的主要功能中get_geo_info_for_this_ip()

不要过分依赖于请求头,如IP数据Client-IPX-Forwarded-For因为他们可以很容易地欺骗,但是你应该依赖于这个实际上是我们的服务器和客户端之间建立的TCP连接的源IP $_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。


0

尝试

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

  ?>

if-else部分将为您提供访问者的IP地址,下一部分将返回国家代码。尝试访问api.wipmania.com,然后访问api.wipmania.com/[your_IP_address ]
Dipanshu Mahla

0

您可以使用我的服务:https : //SmartIP.io,它提供任何IP地址的完整国家名称和城市名称。我们还公开了时区,货币,代理检测,TOR节点检测和加密检测。

您只需要注册并获得一个免费的API密钥,该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


0

截至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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.