У меня есть таблица "пользователи" со столбцами:
Id | user_id | name | ip_address | lat | lng | active
Столбцы широты (широты) и долготы (lng) пустые, и мне нужно заполнить их приблизительным местоположением (мне не нужно точное местоположение). Используя этот форум, в другом вопросе я обнаружил, что мне придется разделять IP-адреса и использовать библиотеку местоположений. Что ж. Я создал функцию для извлечения IP и добавил библиотеку IP2Location в свой проект. Это работает, если я беру IP для IP, получаю широту и долготу и добавляю одну за другой в MySQL, однако у меня 125 000 записей, и я не могу выполнить эту работу вручную. Кто-нибудь знает, как это сделать?
Используя эту функцию
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;
}
У меня есть следующий результат JSON
{
"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"
}
]
}
У меня есть этот скрипт, который может дать мне широту и долготу на основе IP
<?php
require_once './assets/libraries/vendor/ip2location/ip2location-php/IP2Location.php';
$reader = new \IP2Location\Database('./IP2LOCATION-LITE-DB9.BIN', \IP2Location\Database::FILE_IO);
$records = $reader->lookup('8.8.8.8', \IP2Location\Database::ALL);
echo '<pre>';
echo 'IP Number : ' . $records['ipNumber'] . "\n";
echo 'Latitude : ' . $records['latitude'] . "\n";
echo 'Longitude : ' . $records['longitude'] . "\n";
?>
Как автоматически вводить данные о широте и долготе для каждого из IP-адресов?
Извините за количество кода, я стараюсь быть максимально понятным.
Итак, вот функция, которая получает отличные (уникальные) IP-адреса и передает их второй функции для получения Lat/Long и обновления базы данных.
function List_ip() {
global $sqlConnect, $db;
if ($db['loggedin'] == false) {
return false;
}
$ips = mysqli_query($sqlConnect, "SELECT DISTINCT 'ip_address' FROM " . T_USERS . " WHERE 'active' = '1'");
while ($fetched_data = mysqli_fetch_assoc($ips)) {
ip2LocationAndUpdate($fetched_data["ip_address"]); //passing to other function
}
}
Глобальный материал
require_once './assets/libraries/vendor/ip2location/ip2location-php/IP2Location.php';
$reader = new \IP2Location\Database('./IP2LOCATION-LITE-DB9.BIN', \IP2Location\Database::FILE_IO);
Вторая функция, которая делает IP2Location и обновляет sql
function ip2LocationAndUpdate($ip_address){
global $sqlConnect, $reader;
$records = $reader->lookup($ip_address, \IP2Location\Database::ALL);
$updateSQL = "UPDATE " . T_USERS . " SET 'lat' = '$records["latitude"]', 'lat' = '$records["latitude"]' WHERE 'ip_address' = '$ip_address'";
//execute the sql with mysqli or whatever you are using
}
Ответ Nawed Khan решил мою проблему с небольшими изменениями. Это мой код в настоящее время работает на 100%. Спасибо всем за ответ, это было очень полезно для моего изучения языка PHP.
function List_ip() {
global $sqlConnect, $db;
if ($db['loggedin'] == false) {
return false;
}
$ips = mysqli_query($sqlConnect, "SELECT DISTINCT 'ip_address' FROM " . T_USERS . " WHERE 'lat' = '0'");
while ($fetched_data = mysqli_fetch_assoc($ips)) {
ip2LocationAndUpdate($fetched_data["ip_address"]); //passing to other function
}
}
require_once 'assets/libraries/vendor/ip2location/ip2location-php/IP2Location.php';
$reader = new \IP2Location\Database('IP2LOCATION-LITE-DB9.BIN', \IP2Location\Database::FILE_IO);
function ip2LocationAndUpdate($ip_address){
global $sqlConnect, $reader;
$records = $reader->lookup($ip_address, \IP2Location\Database::ALL);
//execute the sql with mysqli or whatever you are using
$latitu = $records['latitude'];
$longitu = $records['longitude'];
$updateSQL = mysqli_query($sqlConnect, "UPDATE " . T_USERS . " SET 'lat' = '$latitu', 'lng' = '$longitu' WHERE 'ip_address' = '$ip_address'");
return $updateSQL;
}
Если у вас слишком много строк для вставки, я бы порекомендовал создать задачу cron для выполнения в фоновом режиме, она быстрее и не влияет на ваш сайт (если она у вас есть)
Поиск crontab. Или shell_exec
Тогда, если вы хотите показать прогресс, вы можете использовать трансляцию или толкать, например,
Используйте плавный алгоритм для решения вашей проблемы
<?php
for($i=1;$i<125000;$i++)
{
// here run what you want to do
}
?>
Примечание: после выполнения 1000 остановка записи на 10 секунд, если вы используете сервер онлайн-сайта
utf8_encode
в контексте результатов БД?utf8_encode
идеале никогда не должен использоваться. Вы знаете, что это делает?