До епохи глобального интернет-сервісу існували локальні бази на серверах, та по IP-адресі визначали місце користувача, який до того сервера звертався. Підтримка актуальності світових даних була не простим завданням і коштувала чималих грошей.
Зараз настав час, коли з'явилися вільні сервіси, що допомогають в питанні визначення місця юзера на глобусі. Один з них ip-api.com, який видає розгорнуту інформацію по запиту (країна, місто, валюта, провайдер, координати та інше):
/* Отримання інформації по IP-адресі */
[PHP]
<?php
$ip = $_SERVER['REMOTE_ADDR'];
$query = @unserialize(file_get_contents('http://ip-api.com/php/' . $ip . '?lang=en'));
echo '<p>'. $query['country'] .' - '. $query['city'] .' - '. $query['zip'] .' - '. $query['timezone'] .' - '. $query['query'] .' - '. $query['isp'] . '</p>';
?>
В скрипті ми визначаємо IP свого серверу через $ip = $_SERVER['REMOTE_ADDR']
і робимо запит в IP-api.com, потім чекаємо відповідь і виводимо її в HTML. Всього три строки, а у відповідь отримаємо про користувача, який завітав на сервер, щось схоже на:
Sweden - Linköping - 58222 - Europe/Stockholm - 77.111.244.25 - Opera Browser VPN
Але, скрипт не спрацює, якщо сервер підключений за роутером. В цьому разі, на REMOTE_ADDR ми отримаємо лише локальну адресу, а нас таке не влаштовує.
Випадок має рішення за допомоги іншого сервісу ipify.org, до якого можна звернутися і отримати необхідну адресу уже ззовні:
$ip = file_get_contents('https://api.ipify.org');
За умови всих дій і використання стилів Berry 4.0, перепишемо попередній скрипт в Albireo таким чином:
/* Отримання інформації по IP-адресі */
[PHP]
$ip = file_get_contents('https://api.ipify.org');
$query = @unserialize(file_get_contents('http://ip-api.com/php/' . $ip . '?lang=en'));
if ($query && $query['status'] == 'success')
{
echo '<p class="t-upper t80">
<img class="pad5-b pad10-r opacity80" src="' . getConfig('assetsUrl') . 'images/flags-iso/shiny/32/' . $query['countryCode'] . '.png">' . $query['country'] . '<span class="t-green400 mar5-rl">★</span>' . $query['city'] . '<span class="t-green400 mar5-rl">★</span>' . $query['zip'] . '<span class="t-green400 mar5-rl">★</span>' . $query['timezone'] . '<span class="t-green400 mar5-rl">★</span><span class="t-nowrap">' . $query['query'] . '</span><span class="t-green400 mar5-rl">★</span>' . $query['isp'] . '</p>';
}
else
{
echo 'Не вдалося виявити локацію.';
}
Вивід ми прикрасили додатково прапором країни, який вже приєднали локально, бо він у відповідь сервісу не входить. Якщо прапорець не потрібен, то можна просто видалити фрагмент коду:
<img class="pad5-b pad10-r opacity80" src="' . getConfig('assetsUrl') . 'images/flags-iso/shiny/32/' . $query['countryCode'] . '.png">'
Кращим варіантом буде написати snippet, з перевіркою можливостей відгуку сервера, поєднавши обидва підходи. В цьому випадку, ми уникаємо проблем роботи з сервером.
/* Отримання інформації по IP-адресі */
[PHP]
$ip = $_SERVER['REMOTE_ADDR'];
$query = @unserialize(file_get_contents('http://ip-api.com/php/' . $ip . '?lang=en'));
if ($query && $query['status'] != 'success')
{
$ip = file_get_contents('https://api.ipify.org');
}
$query = @unserialize(file_get_contents('http://ip-api.com/php/' . $ip . '?lang=en'));
if ($query && $query['status'] == 'success')
{
echo '<p class="t-upper t80"><img class="pad5-b pad10-r opacity80" src="' . getConfig('assetsUrl') . 'images/flags-iso/shiny/32/' . $query['countryCode'] . '.png">' . $query['country'] . '<span class="t-green400 mar5-rl">★</span>' . $query['city'] . '<span class="t-green400 mar5-rl">★</span>lat ' . $query['lat'] . ' - lon ' . $query['lon'] . '<span class="t-green400 mar5-rl">★</span>' . $query['timezone'] . '<span class="t-green400 mar5-rl">★</span><span class="t-nowrap">ip ' . $query['query'] . '</span><span class="t-green400 mar5-rl">★</span>' . $query['isp'] . '</p>';
}
else
{
echo 'Не вдалося виявити локацію.';
}
Кінцевий результат роботи snippet, з додатковими координатами, може бути таким:
United States★Dublin★lat 40.0992 - lon -83.1141★America/New_York★ip 18.217.193.85★Amazon.com, Inc.