【问题标题】:Identifying user's location by IP address通过IP地址识别用户位置
【发布时间】:2012-06-15 01:16:26
【问题描述】:

我正在编写一个程序,希望自动识别用户所在的国家/地区。我编写了获取 ip 并将其存储在数据库中的代码。

$ip = gethostbyname($_SERVER['REMOTE_ADDR']);

存储:

 <?php `$result = mysql_query("INSERT INTO `wh_order` (`name`, `email`, `contact`, `itemid`, `itemquantity`, `ip`,`message`, `date`) VALUES('".$name."','".$email."','".$contact."','".$itemid."','".$itemquantity."','".$ip."','".$message."', NOW())");` ?>

另外,这是存储IP地址的最佳方法吗?

【问题讨论】:

  • 仅通过存储用户的ip如何识别位置?
  • 有各种 API 可以尝试从 IP 建议国家/地区,但这并不可靠,因为它并不总是准确的,并且用户 IP 可能被阻止或者他们可能正在使用 VPN。根据您的需要,您可以查看他们设置的语言环境,但这也有同样的问题。这将是一个最好的猜测。
  • 将 IP 地址存储为 int:daipratt.co.uk/mysql-store-ip-address
  • $_SERVER['REMOTE_ADDR'] 本身会为您提供 IP。您需要安装 Maxmind 的 GeoIP 之类的东西才能从 IP 地址获取国家代码。

标签: php sql geolocation ip


【解决方案1】:

首先,gethostbyname 不会给你一个国家。为此,您必须求助于地理位置。可以正常工作的免费服务是http://freegeoip.net。他们提供了一个 API:

http://freegeoip.net/json/74.125.143.104

返回:

{
    "city": "Mountain View",
    "region_code": "CA",
    "region_name": "California",
    "metrocode": "807",
    "zipcode": "94043",
    "longitude": "-122.057",
    "latitude": "37.4192",
    "country_code": "US",
    "ip": "74.125.227.136",
    "country_name": "United States"
}

请注意,IP 地理定位不会 100% 准确。


存储 IP 地址的最佳列类型是 INT(10) unsigned,它比 varchar 列占用的空间更少。使用INET_ATONINET_NTOA 可以轻松处理转换:

mysql> SELECT INET_ATON('10.0.5.9');
        -> 167773449

mysql> SELECT INET_NTOA(167773449);
        -> '10.0.5.9'

【讨论】:

  • @MatthewRiches INET_ATON/INET_NTOA 目前不支持 IPv6。但是,您可以为此使用 phps inet_pton。
  • 谢谢。但我不理解“INET_ATON”部分。你能详细说明一下吗?我是新手。谢谢。
  • @user1445759 当然可以。插入 IP 时使用 INET_ATON:INSERT INTO table(country, ip) VALUES('United States', INET_ATON('10.0.5.9');。选择时使用 INET_NTOA:SELECT country, INET_NTOA(ip) from table;。有意义吗?
  • 好的。有一定道理。类似于加密-解密类型。谢谢。
  • freegeoip.net 听起来不错,但不知道它们。不过,他们停止更新 IP 数据库,因为 IPInfoDB 不再免费。 "该数据库最后一次更新是在 2011 年 4 月 29 日"
【解决方案2】:

通过 IP 识别用户的位置称为Geolocation。它通常需要一个将 IP 地址范围映射到地理位置的数据库。

Maxmind 公司根据 CreativeCommons 许可免费提供了一个名为 GeoLite 的数据库

GeoLite 数据库根据知识共享协议获得许可 Attribution-ShareAlike 3.0 未移植许可证。商业许可是 可用。

他们有一个允许快速 IP 查找的 apache 模块,然而,最简单的入门方法可能是纯 PHP 选项。查看list of possible integration methods.

下载档案包括几个例子,基本过程相当简单:

$gi = geoip_open("GeoLite.dat", GEOIP_STANDARD);
$record = geoip_record_by_addr($gi, "24.24.24.24");
echo $record->latitude;
echo $record->longitude;

【讨论】:

    【解决方案3】:

    您可以将 maxmind (http://www.maxmind.com/app/country) 的数据库与 apache 或 nginx 扩展结合使用。

    或者,有一个很好的库来完成这个任务:http://geocoder-php.org/

    【讨论】:

      【解决方案4】:

      使用https://geoip-db.com的服务他们支持IPV4和IPV6地址来定位ip的地理位置。

      示例:

      <!DOCTYPE html>
      <html>
      <head>
          <title>GEOIP DB - Geolocation by IP</title>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js">
          </script>
      </head>
      <body>
          <div>Country: <span id="country"></span>
          <div>State: <span id="state"></span>
          <div>City: <span id="city"></span>
          <div>Latitude: <span id="latitude"></span>
          <div>Longitude: <span id="longitude"></span>
          <div>IP: <span id="ip"></span>
          <script>
              $.ajax({
                  url: "https://geoip-db.com/jsonp",
                  jsonpCallback: "callback",
                  dataType: "jsonp",
                  success: function( location ) {
                      $('#country').html(location.country_name);
                      $('#state').html(location.state);
                      $('#city').html(location.city);
                      $('#latitude').html(location.latitude);
                      $('#longitude').html(location.longitude);
                      $('#ip').html(location.IPv4);  
                  }
              });     
          </script>
      </body>
      </html>
      

      这是一个 jquery sn-p,尽管可以在他们的网站上找到其他示例(普通 javascript、php、C#)

      【讨论】:

        猜你喜欢
        • 2016-08-21
        • 1970-01-01
        • 2015-07-31
        • 2011-08-02
        • 2018-03-30
        • 1970-01-01
        • 2014-11-07
        • 1970-01-01
        相关资源
        最近更新 更多