PHP не имеет каких то специальных средств для определения ip адреса. Эту информацию ему поставляет веб-сервер в виде переменных окружения.
Используя команду phpinfo(), можно получить список переменных окружения, настроек сервера, подключенных библиотек. Нас интересует удаленный адрес посетителя. В этой таблице он идет под именем «REMOTE_ADDR».
Вот пример, с моего локального тестового сервера:
Эта информация попадает в глобальную переменную-массив $_SERVER. Т.е. определить адрес пользователя очень просто —
1 |
$ip = $_SERVER[‘REMOTE_ADDR’]; |
В некоторых случаях переменные окружения могут быть подменены. К примеру, когда трафик проходит через прокси, обычно в качестве REMORE_ADDR выступает уже адрес прокси-сервера. Но программное обеспечение сохраняет адрес клиента в заголовке HTTP запроса. В переменные окружения этот адрес может попасть под разными именами.
Пример функции, извлекающей ip адрес, используя несколько переменных окружения.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
/** * Получить IP адрес клиента * @return string */ function getClientIp() { if (getServer('HTTP_CLIENT_IP') != null) { $ip = getServer('HTTP_CLIENT_IP'); } else if (getServer('HTTP_X_FORWARDED_FOR') != null) { $ip = getServer('HTTP_X_FORWARDED_FOR'); } else { $ip = getServer('REMOTE_ADDR'); } return $ip; } /** * Получить данные из массива _SERVER * @param null $key * @param null $default * @return null */ function getServer($key = null, $default = null) { if ($key === null) return $_SERVER; return (isset($_SERVER[$key])) ? $_SERVER[$key] : $default; } |
В данном примере перебираются варианты названий переменной окружения. Сначала анализируется значение из $_SERVER[‘HTTP_CLIENT_IP’], потом проверяется в ‘HTTP_X_FORWARDED_FOR’ и в заключении в ‘REMOTE_ADDR’.
Доверять значению, передаваемому в переменных ‘HTTP…’ нельзя, так как эти значения передаются через заголовки HTTP запроса и могут содержать произвольную информацию. Их можно сохранить в качестве дополнения к значению ‘REMOTE_ADDR’.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/** * Получить IP адреса клиента * @return array */ function getClientIpInfo() { $ip = array('addr' => $_SERVER['REMOTE_ADDR']); if (!empty($_SERVER['HTTP_CLIENT_IP'])) $ip['client_addr'] = $_SERVER['HTTP_CLIENT_IP']; if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) $ip['forwarded_addr'] = $_SERVER['HTTP_X_FORWARDED_FOR']; return $ip; } |
Этот набор информации уже можно протоколировать, сохранять и использовать для анализа. Можно добавить проверку информации в переменных ‘HTTP..’ на соответствие формату, чтобы не сохранять то, что вам не нужно.
Здравствуйте!
Скажите, пожалуйста, как вывести ip-адрес на сайте правильно.
Вывожу так:
Выводятся два одинаковых ip-адреса. Если вывести так:
То выводится соответственно:
Array
(
[addr] => 00.00.0.00
[forwarded_addr] => 00.00.0.00
)
Спасибо!
С уважением, Дмитрий
Вывожу так:
php foreach($ip as $ip_info):
$ip_info
php endforeach;
В предыдущем сообщении вырезало, поэтому знаки лишние убрал сейчас.
Смысл статьи в том, что есть несколько переменных окружения, где может содержаться информация об ip пользователя. Вы можете принять какую то систему приоритетов, например, как это сделано в функции getClientIp(), а можете получить набор адресов, как в функции getClientIpInfo().
Обычно, достаточно запросить $ip_address = $_SERVER[‘REMOTE_ADDR’], но если сайт находится за прокси сервером, то надо делать более сложные манипуляции.
Пример получения ip_address из CMS Drupal:
function ip_address() {
static $ip_address = NULL;
if (!isset($ip_address)) {
$ip_address = $_SERVER[‘REMOTE_ADDR’];
if (variable_get(‘reverse_proxy’, 0) && array_key_exists(‘HTTP_X_FORWARDED_FOR’, $_SERVER)) {
// If an array of known reverse proxy IPs is provided, then trust
// the XFF header if request really comes from one of them.
$reverse_proxy_addresses = variable_get(‘reverse_proxy_addresses’, array());
if (!empty($reverse_proxy_addresses) && in_array($ip_address, $reverse_proxy_addresses, TRUE)) {
// If there are several arguments, we need to check the most
// recently added one, i.e. the last one.
$ip_address_parts = explode(‘,’, $_SERVER[‘HTTP_X_FORWARDED_FOR’]);
$ip_address = array_pop($ip_address_parts);
}
}
}
return $ip_address;
}