在PHP中获取客户端的IP地址是非常常见的需求,在本文中我们将介绍几种常用的获取IP函数。
一、$_SERVER['REMOTE_ADDR']
PHP中获取IP地址的最简单方法是使用$_SERVER['REMOTE_ADDR'],这个变量保存了客户端的IP地址,但是它并不总是可靠的。客户端可以通过代理服务器或者VPN等方式隐藏或者修改自己的IP地址,这样就会造成误判。
二、获取HTTP头信息
HTTP头信息中有几个关键信息可以帮助我们获取客户端的真实IP地址。
1. $_SERVER['HTTP_X_FORWARDED_FOR']
这个变量可以获取客户端经过代理服务器后的真实IP地址,如果客户端没有经过代理服务器,这个变量的值将是NULL。
2. $_SERVER['HTTP_CLIENT_IP']
这个变量用来获取客户端真实的IP地址,但是它只能在某些情况下才能获取,比如客户端使用的是Netscape浏览器。
3. $_SERVER['HTTP_X_REAL_IP']
一些特定的代理服务器会添加这个变量来代替X-Forwarded-For头信息,它也可以被用来获取客户端的真实IP地址。
这些HTTP头信息可以一起使用来获取客户端的真实IP地址,例如:
```
function get_real_ip() {
$ip = '';
//HTTP_X_FORWARDED_FOR可以获取客户端IP地址和代理服务器IP地址,用“,”分割
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && !empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip_list = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
foreach ($ip_list as $client_ip) {
if (filter_var($client_ip, FILTER_VALIDATE_IP)) {
$ip = $client_ip;
break;
}
}
} elseif (isset($_SERVER['HTTP_CLIENT_IP']) && !empty($_SERVER['HTTP_CLIENT_IP'])) {
if (filter_var($_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP)) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
}
} elseif (isset($_SERVER['HTTP_X_REAL_IP']) && !empty($_SERVER['HTTP_X_REAL_IP'])) {
if (filter_var($_SERVER['HTTP_X_REAL_IP'], FILTER_VALIDATE_IP)) {
$ip = $_SERVER['HTTP_X_REAL_IP'];
}
} else {
if (isset($_SERVER['REMOTE_ADDR']) && !empty($_SERVER['REMOTE_ADDR'])) {
if (filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP)) {
$ip = $_SERVER['REMOTE_ADDR'];
}
}
}
return $ip;
}
```
这个函数会先尝试使用HTTP_X_FORWARDED_FOR来获取客户端的真实IP地址,如果获取失败再尝试其他的HTTP头信息来获取客户端的IP地址,最后使用$_SERVER['REMOTE_ADDR']来作为备用方案。
三、使用PHP扩展
除了以上基于HTTP头信息的方法外,还有一些PHP扩展可以用来获取客户端的IP地址。
1. Swoole扩展
Swoole是一个常用的PHP扩展,它通过swoole_http_request->server['remote_addr']来获取客户端的IP地址,这个方法与$_SERVER['REMOTE_ADDR']的效果是一样的。
2. Yaf扩展
Yaf是另一个常用的PHP扩展,使用Yaf可以使用getRequest()->getClientIp()来获取客户端的IP地址。
四、总体方案
综合以上几种方法,我们可以得出一个完整的获取客户端IP地址的方案,代码如下:
```
function get_client_ip_address() {
$ip = '';
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && !empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip_list = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
foreach ($ip_list as $client_ip) {
if (filter_var($client_ip, FILTER_VALIDATE_IP)) {
$ip = $client_ip;
break;
}
}
} elseif (isset($_SERVER['HTTP_CLIENT_IP']) && !empty($_SERVER['HTTP_CLIENT_IP'])) {
if (filter_var($_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP)) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
}
} elseif (isset($_SERVER['HTTP_X_REAL_IP']) && !empty($_SERVER['HTTP_X_REAL_IP'])) {
if (filter_var($_SERVER['HTTP_X_REAL_IP'], FILTER_VALIDATE_IP)) {
$ip = $_SERVER['HTTP_X_REAL_IP'];
}
} else {
if (isset($_SERVER['REMOTE_ADDR']) && !empty($_SERVER['REMOTE_ADDR'])) {
if (filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP)) {
$ip = $_SERVER['REMOTE_ADDR'];
}
}
}
return $ip;
}
```
这个函数会优先尝试使用HTTP_X_FORWARDED_FOR来获取客户端的真实IP地址,如果获取失败再尝试其他的HTTP头信息来获取客户端的IP地址,最终使用$_SERVER['REMOTE_ADDR']作为备用方案。
五、防范欺骗
为了防止客户端伪造IP地址造成的欺骗行为,我们可以对IP地址进行过滤,只接受特定的IP地址。例如:
```
function get_client_ip_address($trusted_ips) {
$ip = '';
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && !empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip_list = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
foreach ($ip_list as $client_ip) {
if (filter_var($client_ip, FILTER_VALIDATE_IP) && in_array($client_ip, $trusted_ips)) {
$ip = $client_ip;
break;
}
}
} elseif (isset($_SERVER['HTTP_CLIENT_IP']) && !empty($_SERVER['HTTP_CLIENT_IP'])) {
if (filter_var($_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP) && in_array($_SERVER['HTTP_CLIENT_IP'], $trusted_ips)) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
}
} elseif (isset($_SERVER['HTTP_X_REAL_IP']) && !empty($_SERVER['HTTP_X_REAL_IP'])) {
if (filter_var($_SERVER['HTTP_X_REAL_IP'], FILTER_VALIDATE_IP) && in_array($_SERVER['HTTP_X_REAL_IP'], $trusted_ips)) {
$ip = $_SERVER['HTTP_X_REAL_IP'];
}
} else {
if (isset($_SERVER['REMOTE_ADDR']) && !empty($_SERVER['REMOTE_ADDR']) && in_array($_SERVER['REMOTE_ADDR'], $trusted_ips)) {
if (filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP)) {
$ip = $_SERVER['REMOTE_ADDR'];
}
}
}
return $ip;
}
```
这个函数在获取客户端IP地址后,会对IP地址进行过滤,只返回属于$trusted_ips数组中的IP地址。
六、其他注意事项
1. 请注意,客户端IP地址可能会伪造,因此在对IP地址进行处理时需要进行严格的过滤和校验,以防止欺骗行为。
2. 在使用缓存或者负载均衡时,客户端IP地址可能会因为中间网络设备的转发而改变,因此需要注意防范。
3. 在命令行模式下获取客户端IP地址是不可行的,因为这个时候本身就是一个服务端,而不是一个客户端。 如果你喜欢我们三七知识分享网站的文章, 欢迎您分享或收藏知识分享网站文章 欢迎您到我们的网站逛逛喔!https://www.ynyuzhu.com/
发表评论 取消回复