【问题标题】:Populate Latitude and Longitude in the database from the user's IP从用户的 IP 填充数据库中的纬度和经度
【发布时间】:2019-04-15 17:01:02
【问题描述】:

我有一个包含列的“用户”表:

Id | user_id | name | ip_address | lat | lng

id 列、user_id、name 和 ip_address 已填充,现在有 100k 用户。 现在已经创建了 lat(纬度)和 lng(经度)列,我需要从 IP 填充它们(您无法获取用户的地理位置)。 我不想要精确的位置,只想要大概的位置,所以我需要一个脚本来获取每个用户的IP,以某种方式提取纬度和经度,然后插入到数据库中。

我看过“http://www.geoplugin.net/xml.gp?ip=”和“http://ip-api.com/json/”,但我不知道如何为 10 万用户使用 api,也不知道如何使用 PHP 或 mysql 代码或 shell。

我只使用 PHP、MySQLi 和 MySQL 数据库。该应用程序将显示“附近”(半径 100 英里内)的用户列表。

对不起,我对编程很陌生,我真的不知道如何解决这个问题。

编辑:

我刚刚创建了一个 api,它在一个数组中返回所有 user_id 和它们各自的 IP。 只是 105k 的记录,对于 json,它很轻,但我不想在这里公开分享 json,因为这与解释我的用户数据相同。 api 的结果是这样的:

{
     "api_status": 200,
     "ips": [
         {
             "user_id": "1",
             "ip_address": "177.198.86.7x"
         },
         {
             "user_id": "21",
             "ip_address": "177.18.246.9x"
         },
         {
             "user_id": "52",
             "ip_address": "177.36.60.1x"
         }
     ]
}

我正在使用以下函数在 php 中返回我的数据

function List_ip() {
    global $sqlConnect, $db;
    if ($db['loggedin'] == false) {
        return false;
    }

    $ips = mysqli_query($sqlConnect, "SELECT `user_id` , `ip_address` FROM " . T_USERS . " WHERE `active` = '1'");
    while ($fetched_data = mysqli_fetch_assoc($ips)) {
     $list_ip[] = array_map('utf8_encode', $fetched_data); 
    }    

   return $list_ip;

}

【问题讨论】:

  • ip-api 仅允许每分钟来自 IP 地址的 150 个请求。如果超出此范围,您的 IP 地址将被列入黑名单。要获取数据,您可以使用 PHP CURL
  • 您将需要学习如何在 php 中使用外部 API,您的问题中没有太多关于您使用哪些其他框架来显示此数据的信息。对于这样的一次性工作,您也可以编写一个简单的控制台或节点应用程序。
  • 感谢支持,不知道这个限制。所以我必须做一个限制每秒请求数的脚本,对吗?是否有示例说明如何发出 cURL 请求并施加每秒限制?
  • Adil H. Raza 我没有使用框架。该应用程序是用纯 PHP 开发的,并用作应用程序后端。项目只使用纯PHP、mysqli和数据库mysql。

标签: php mysql geolocation


【解决方案1】:

我对限制请求数量没有太多想法,但请尝试以下代码从 ip-api 获取详细信息。

    $url = "http://ip-api.com/batch";

$headers = array('Content-Type: application/json');

$fields = '[{"query": "208.80.152.201"}, // You can add multiple IP address in the same format.
  {"query": "8.8.8.8"},
  {"query": "24.48.0.1"}]';


$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_POSTFIELDS, $fields);
$httpCode = curl_getinfo($curl , CURLINFO_HTTP_CODE); 
$response = curl_exec($curl);

if ($response === false) 
    $response = curl_error($curl);

  foreach(json_decode($response) as $value){


    echo $value->lat; //Use the result to store the information in DB
  }



curl_close($curl);

请参考他们的documentation,了解他们的 API 返回的数据。

另外,为了限制,试试this solution

【讨论】:

    【解决方案2】:

    maxmind/GeoIP2-php 应该可以满足您的需求。

    安装它并下载GeoIP2-City.mmdb 文件。

    不仅仅是启动它的问题:

    $record = new Reader('path/to/GeoLite2-City.mmdb');
    

    并从中读取数据,例如:

    $city = $record->city->name;
    $latitude = $record->location->latitude;
    $longitude = $record->location->longitude;
    

    这样做意味着对第三方 API 限制的零依赖。

    【讨论】:

    • 嗨,这会让我没有每秒请求限制吗?如果是这样,我一定会看的!谢谢。
    【解决方案3】:

    您要求的内容需要 PHP 和 MySQL 等中级技能。我已经做过很多这样的事情,并且会告诉您,首先要获得准确的 GEO IP 信息,您必须使用 javascript 或支付服务费用(根据我的发现)。比如www.maxmind.com 有免费和付费,付费的好一点。

    我会尝试编写一个脚本,循环读取数据库中的所有用户,然后下载 geopip 或使用 api 获取 IP 字段并返回 Lat/Lon。然后最后添加将其写回数据库的步骤。

    一个非常粗略的例子:

    // build a class or function that looks up IP addresses (can be local)
    $geoip2 = new GeoIp2Lookup(true);
    
    // get all users from DB
    $allUsersArray = function_results_db_lookup_users();
    
    // get the users lat/lon
    for ($i=0; $i<count($allUsersArray); $i++) {
      $record = $geoip2->getGeoDataArr($allUsersArray[$i]['ip_address']);
      $allUsersArray[$i]['lat'] = $record['lat'];
      $allUsersArray[$i]['lon'] = $record['lon'];
    }
    
    // now write a function to place in DB the new data
    update_users_db($allUsersArray);
    

    【讨论】:

    • 我明白这需要我没有的技能,所以我去了这个很棒的平台。我无法想象我的应用程序会达到 10 万用户,即使因为我用 1 个月的 PHP 学习开发它。我正在努力研究这一切是如何运作的,但我真的需要帮助,因为没有比我更好的人的经验,我将一事无成。感谢您的评论
    • 我更新了代码,大致了解了它作为命令行脚本的工作原理,但我没有包含如何与数据库交互或使用 maxmind 查找地理信息的代码(我过去用过)..
    • 这对我来说似乎很有用。我会尽力。谢谢。
    • 如果您愿意,我愿意为您提供帮助.... 我将首先创建一个 php 脚本,您可以从命令行运行该脚本,该脚本可以执行 mysql SELECT * FROM users 并放入一个数组并打印。
    • Mike Q 非常感谢您的帮助。我用更多数据编辑了这个问题。我在 PHP 中做了一个函数来获取数据。我现在如何使用您推荐给我的库?抱歉这么懒,我以前从来没有用过这个。
    【解决方案4】:

    您可以在https://www.ip2location.com/development-libraries/ip2location/php 轻松使用免费的 IP2Location PHP 模块。

    要安装,请将以下行添加到您的 composer.json 文件中。

    {
      "require": {
        "ip2location/ip2location-php": "8.*"
      }
    }
    

    运行命令:

    composer install
    

    注意:您只需要包含以下代码即可使用该库。

    require 'vendor/autoload.php';
    

    您需要 DB5.LITE 数据库,您可以通过https://lite.ip2location.com/免费下载该数据库

    PHP 模块使用示例

    <?php
    require 'IP2Location.php';
    
    $myip = '8.8.8.8';
    
    $db = new \IP2Location\Database('./database/IP-COUNTRY-SAMPLE.BIN', \IP2Location\Database::FILE_IO);
    
    $records = $db->lookup($myip, \IP2Location\Database::ALL);
    
    echo '<pre>';
    echo 'IP Address            : ' . $records['ipAddress'] . "\n";
    echo 'Country Code          : ' . $records['countryCode'] . "\n";
    echo 'Country Name          : ' . $records['countryName'] . "\n";
    echo 'Region Name           : ' . $records['regionName'] . "\n";
    echo 'City Name             : ' . $records['cityName'] . "\n";
    echo 'Latitude              : ' . $records['latitude'] . "\n";
    echo 'Longitude             : ' . $records['longitude'] . "\n";
    echo '</pre>';
    ?>
    

    【讨论】:

    • 谢谢,我一定会试试的。但是我将如何使用 json 发送所有 IP 并将它们取回,或者将它们写入数据库?
    • 模块接受单个 IP 地址。因此,您需要循环您的 IP 数组并查询每个 IP 的 IP2Location 模块。然后使用基于 IP 地址的结果更新您的数据库。
    • 谢谢,我将研究 PHP 中的循环来尝试解决这个问题。无论如何,您是否建议我循环通过捕获的 IP,并在同一个循环中记录数据库中的纬度和经度?我想我理解你的推理,我只是不知道如何运行它,但是谢谢。
    • 是的,当您查询每个 IP 并获得结果时,您还需要更新数据库。
    猜你喜欢
    • 2019-08-04
    • 1970-01-01
    • 2012-12-06
    • 1970-01-01
    • 2023-03-31
    • 2016-05-21
    • 1970-01-01
    • 2013-07-07
    • 2011-08-04
    相关资源
    最近更新 更多