У цій статті розглянемо одну з поширених задач у програмуванні на PHP. А саме — як у PHP визначити IP користувача.
Якщо я працюю не з фреймворком (наприклад, таким як Yii), то використовую одне з готових рішень у вигляді наступної функції:
function user_ip()
{
if(getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"),"unknown"))
{
return getenv("HTTP_CLIENT_IP");
}
else if(getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown"))
{
return getenv("HTTP_X_FORWARDED_FOR");
}
else if(getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown"))
{
return getenv("REMOTE_ADDR");
}
else if(!empty($_SERVER['REMOTE_ADDR']) && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown"))
{
return $_SERVER['REMOTE_ADDR'];
}
return NULL;
}У результаті ця функція може повернути один із двох варіантів значень:
1. IP користувача
2. NULL, якщо визначити IP не вдалося.
Давайте розглянемо приклад вище детальніше. У листингу використовуються наступні функції:
getenv() — Отримує значення змінної середовища
strcasecmp() — Виконує бінарно-безпечне порівняння рядків без врахування регістру
empty() — Перевіряє, чи є змінна порожньою
У змінних середовища `getenv("HTTP_CLIENT_IP")` або `getenv("HTTP_X_FORWARDED_FOR")` зберігається оригінальна IP-адреса користувача. Тут усе залежить від самого проксі-сервера. За бажанням (а точніше — його конфігурацією), він може або повертати IP користувача, або не повертати його. Провівши невеликий тест із двома проксі-серверами, було виявлено, що ці змінні були порожніми.
А ось наступні конструкції:
if(getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown"))
{
return getenv("REMOTE_ADDR");
}
else if(!empty($_SERVER['REMOTE_ADDR']) && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown"))
{
return $_SERVER['REMOTE_ADDR'];
}Будуть повертати або IP-адресу самого користувача, або IP-адресу проксі-сервера.
Але навіть у разі невдачі — повертати NULL, що дозволяє коректніше обробляти дані.
