【问题标题】:Get Country of IP Address with PHP [duplicate]使用PHP获取IP地址的国家[重复]
【发布时间】:2011-04-08 16:17:18
【问题描述】:

理想情况下,我会尝试编写一个 PHP 脚本,我可以从任何 Web 浏览器查询它,它会返回访问 PHP 脚本的 IP 地址所在的国家/地区。

这是可能的还是有更好的解决方案?

【问题讨论】:

  • 强制性说明:由于各种代理、VPN 和其他恐怖因素,IP 定位不是一种可靠的来源识别方法。根据IP地址,我现在在德克萨斯、挪威、捷克和日本。
  • IPLocate.io 提供免费 API:https://www.iplocate.io/api/lookup/8.8.8.8 - 免责声明:我运行此服务。
  • 要获得快速可靠的解决方案,您应该尝试 Ipregistry.co:api.ipregistry.co/?key=tryout(免责声明:我运行该服务)。

标签: php geolocation ip-address geoip ip-geolocation


【解决方案1】:

查看“其他基本扩展”下的 GeoIP 功能。 http://php.net/manual/en/book.geoip.php

【讨论】:

【解决方案2】:

您可以使用免费、简单的 API,例如:

哪个看起来最值得信赖取决于你:)

否则,有些脚本基于您服务器上的本地数据库。但是,数据库数据需要定期更新。看看这个:

HTH!

编辑: 当然,根据您的项目,您可能希望查看HTML5 Location 功能。您还不能在 Internet Explorer 上使用它们(IE9 将支持它,还有很长的路要走),但如果您的受众主要在移动设备上或使用 Safari/Firefox,那么绝对值得一看!

获得坐标后,您可以将其反向地理编码为国家/地区代码。还有像这样的 API:

2013 年 4 月更新
今天我推荐使用Geocoder,这是一个 PHP 库,可以很容易地对 IP 地址和邮政地址数据进行地理编码。

***2016 年 9 月更新
由于 Google 的隐私政策发生了变化,如果您的服务器没有 HTPPS 证书或用户不允许您查看他的位置,您将无法使用 HTML5 Geolocation API。所以现在您可以使用用户的 IP 并签入 PHP 或获取 HTTPS 证书。

【讨论】:

  • 我认为自从发布答案以来这个 api 发生了一些变化,我现在收到以下错误:“GoogleMaps 提供商不支持 IP 地址,只支持街道地址。”
  • ipregistry.co 比 ipdata.co 快两倍且准确:ipregistry.co/status(免责声明:我运行该服务)
【解决方案3】:

您可以从 MaxMind 下载 ip-tables:

http://www.maxmind.com/app/geolite

将 CSV 导入数据库(确保为 ip_long_from + ip_long_to 创建索引)。然后你可以简单地做:

$iplong = ip2long($_SERVER['REMOTE_ADDR']);

// should use mysqli with prepared statements etc, but just an example
mysql_query("
    SELECT country
    FROM ip_table
    WHERE $iplong BETWEEN ip_long_from AND ip_long_to
    LIMIT 1
");

【讨论】:

  • 这个,这是从 IP 地址获取国家/地区的绝佳方式。
  • 我不明白人们如何获得本地化的城市/国家名称,因为 geolite 只提供几种语言
  • 最令人惊奇的是,为“from”和“to”列添加索引使查询时间延长了 10 倍。保持数据库未编入索引对我来说效果最好,再加上 LIMIT 1。也许是因为数据是在 CSV 中排序的。去图吧。
【解决方案4】:

使用小部件www.feedsalive.com,获取国家信息和最后一页信息。

【讨论】:

    【解决方案5】:

    有多种网络 API 可以为您完成此任务。这是一个使用我的服务的示例,http://ipinfo.io

    $ip = $_SERVER['REMOTE_ADDR'];
    $details = json_decode(file_get_contents("http://ipinfo.io/{$ip}"));
    echo $details->country; // -> "US"
    

    Web API 是一个不错的快速简便的解决方案,但如果您需要进行大量查找,那么在您自己的机器上拥有一个 IP -> 国家/地区数据库是一个更好的解决方案。 MaxMind 提供了一个 free database,您可以将其与各种 PHP 库一起使用,包括 GeoIP

    【讨论】:

    • 我会避免在生产环境中实现 ipinfo.io。我刚刚确定了我们脚本中的主要滞后,一个调用 ipinfo.io 以获取 IP 详细信息的函数。确保彻底测试您的提供商选择:)
    • 过去可能确实如此,但它们现在托管在多个提供商和多个城市,以实现最大的可用性和响应能力 - twitter.com/ipinfoio/status/458100167439159296
    • 它不能正常工作。 “193.238.152.59”被识别为FR,但它是UA。
    • 我建议尝试Ipregistry(免责声明:我运行该服务)。
    【解决方案6】:

    我发现这篇博文很有帮助。它拯救了我的一天。 http://www.techsirius.com/2014/05/simple-geo-tracking-system.html

    基本上你需要安装IP数据库表,然后用mysql查询IP的位置。

    <?php
    include 'config.php';
    mysql_connect(DB_HOST, DB_USER, DB_PASSWORD) OR die(mysql_error());
    mysql_select_db(DB_NAME) OR die(mysql_error());
    $ip =  $_SERVER['REMOTE_ADDR'];
    $long = sprintf('%u', ip2long($ip));
    $sql = "SELECT * FROM `geo_ips` WHERE '$long' BETWEEN `ip_start` AND `ip_end`";
    $result = mysql_query($sql) OR die(mysql_error());
    $ip_detail = mysql_fetch_assoc($result);
    if($ip_detail){
        echo $ip_detail['country']."', '".$ip_detail['state']."', '".$ip_detail['city'];
    }
    else{
        //Something wrong with IP
    }
    

    【讨论】:

    • 好吧,我可以先解释一下,因为这是我的第一个或第二个帖子,字数不够,所以一位版主给了这个帖子一个负面的观点,但我不知道第二个。
    【解决方案7】:

    这是一个使用http://www.geoplugin.net/json.gp的例子

    $ip = $_SERVER['REMOTE_ADDR'];
    $details = json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip={$ip}"));
    echo $details;
    

    【讨论】:

      【解决方案8】:

      这是另一个用于地理定位请求的免费 API: http://geoip.nekudo.com

      响应采用 JSON 格式。此外,如果您需要设置自己的 API,可以在 github 上找到 API 源代码。

      【讨论】:

        【解决方案9】:

        如果您需要一个良好且更新的数据库,以获得更高的性能并且不从您的网站请求外部服务,here 是一个下载更新和准确数据库的好地方。

        我之所以推荐这个,是因为根据我的经验,即使包括我的 IP 的城市和国家/地区位置,大多数其他数据库/api 都未能包含/报告我的位置,但 this service 将我引导到此数据库。
        (我测试时的ip位置来自“伊朗”的“拉什特”市,ip为:2.187.21.235等于45815275

        因此,如果您不确定哪种服务更准确,我建议您使用这些服务:

        数据库: http://lite.ip2location.com/databases

        API 服务: http://ipinfodb.com/ip_location_api.php

        【讨论】:

          【解决方案10】:

          我看到有很多答案,但没有一个提到https://freegeoip.net/

          您最多可以使用15,000 queries per hour。我认为在大多数情况下这已经足够了。否则,您应该考虑使用来自MaxMind GeoIP 的本地数据库。

          Freegeoip 是开源的,您可以在 github 上找到源代码,将其部署到本地并摆脱查询限制。

          此外,服务还提供纬度/经度/时区和其他有用的东西。

          【讨论】:

            【解决方案11】:
            $country_code = trim(file_get_contents("http://ipinfo.io/{$ip_address}/country"))
            

            将为您提供国家/地区代码。

            【讨论】:

              【解决方案12】:

              您可以使用此location API 从 IP 地址获取国家/地区

              代码

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

              回应

                 US 
              

              这是fiddle。当您查询特定字段时,响应为text,例如country 在这里。无需解码,只需将其插入您的代码即可。

              附:如果您想要所有字段,例如https://ipapi.co/8.8.8.8/json/,回复是JSON

              【讨论】:

              • 我使用ipapi.co 几个月了,但在进行了 300-400 次查询(每天 4-5 次)之后,他们已经停止处理我的 IP(HTTP/1.1 429 Too Many Requests)。他们网站上的信息每天 1000 次免费查询是不正确的!如果您正在寻找免费服务,我不推荐他们。
              【解决方案13】:

              如果可以,请安装并使用PHP's GeoIP extension。在 debian lenny 上:

              sudo wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
              sudo gunzip GeoLiteCity.dat.gz
              sudo mkdir -v /usr/share/GeoIP
              sudo mv -v GeoLiteCity.dat /usr/share/GeoIP/GeoIPCity.dat
              
              sudo apt-get install php5-geoip
              # or sudo apt-get install php-geoip for PHP7
              

              然后在 PHP 中尝试一下:

              $ip = $_SERVER['REMOTE_ADDR'];
              $country = geoip_country_name_by_name($ip);
              echo 'The current user is located in: ' . $country;
              

              返回:

              The current user is located in: Cameroon
              

              【讨论】:

                【解决方案14】:

                你可以试试https://www.geoip-db.com的服务,他们提供了JSON或者JSONP-callback的解决方案。

                <?php
                
                    $json = file_get_contents("https://www.geoip-db.com/json");
                    $data = json_decode($json);
                
                    print $data->country_code . "<br>";
                    print $data->country_name . "<br>";
                    print $data->state . "<br>";
                    print $data->city . "<br>";
                    print $data->postal . "<br>";
                    print $data->latitude . "<br>";
                    print $data->longitude . "<br>";
                    print $data->IPv4 . "<br>";
                
                ?>
                

                【讨论】:

                  【解决方案15】:

                  您可以使用https://ip-api.io/ 获取国家名称、城市名称、经纬度。它支持 IPv6。

                  作为奖励,它会判断 ip 地址是一个 tor 节点、公共代理还是垃圾邮件发送者。

                  PHP 代码:

                  $result = json_decode(file_get_contents('http://ip-api.io/json/64.30.228.118'));
                  var_dump($result);
                  

                  输出:

                  {
                  "ip": "64.30.228.118",
                  "country_code": "US",
                  "country_name": "United States",
                  "region_code": "FL",
                  "region_name": "Florida",
                  "city": "Fort Lauderdale",
                  "zip_code": "33309",
                  "time_zone": "America/New_York",
                  "latitude": 26.1882,
                  "longitude": -80.1711,
                  "metro_code": 528,
                  "suspicious_factors": {
                  "is_proxy": false,
                  "is_tor_node": false,
                  "is_spam": false,
                  "is_suspicious": false
                  }
                  

                  【讨论】:

                    【解决方案16】:

                    我在IPLocate.io 运行该服务,您可以通过一个简单的电话免费连接:

                    <?php
                    $res = file_get_contents('https://www.iplocate.io/api/lookup/8.8.8.8');
                    $res = json_decode($res);
                    
                    echo $res->country; // United States
                    echo $res->continent; // North America
                    echo $res->latitude; // 37.751
                    echo $res->longitude; // -97.822
                    
                    var_dump($res);
                    

                    $res 对象将包含您的地理位置字段,例如 countrycity 等。

                    查看docs了解更多信息。

                    【讨论】:

                      【解决方案17】:

                      Ipdata.co 提供了一个可扩展的 API 来执行此操作。拥有 10 个全球端点,每个端点每天能够处理超过 8 亿个请求!

                      它还为您提供来自任何 IPv4 或 IPv6 地址的组织、货币、时区、调用代码、标志和 Tor 出口节点状态数据。

                      在php中

                      php > $ip = '8.8.8.8';
                      php > $details = json_decode(file_get_contents("https://api.ipdata.co/{$ip}"));
                      php > echo $details->region;
                      California
                      php > echo $details->city;
                      Mountain View
                      php > echo $details->country_name;
                      United States
                      php > echo $details->location;
                      37.405991,-122.078514
                      

                      免责声明

                      我构建了这个服务。

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2012-03-08
                        • 1970-01-01
                        • 1970-01-01
                        • 2013-11-05
                        相关资源
                        最近更新 更多