📅  最后修改于: 2023-12-03 15:11:51.647000             🧑  作者: Mango
获取客户端 PHP 的 IP 地址
在开发 PHP 项目过程中,我们经常需要获取客户端的 IP 地址,以此来记录访问日志、做访问限制等操作。但是,由于客户端 IP 的获取方式存在多种,开发者可能会比较困惑。本文将介绍几种获取客户端 PHP 的 IP 地址的方式。
在 PHP 的 $_SERVER 数组中,存储了客户端的 IP 地址。一般情况下,$_SERVER 数组中的 REMOTE_ADDR 键值存储了客户端的 IP。我们可以通过如下代码来获取:
$ip = $_SERVER['REMOTE_ADDR'];
需要注意的是,由于 HTTP 可被代理,因此 REMOTE_ADDR 中的 IP 地址有时会是代理服务器的 IP 地址,而非真正的客户端 IP 地址。
为了解决代理服务器带来的问题,HTTP 协议定义了 X-Forwarded-For 首部,用于传递真实的客户端 IP 地址。有些代理服务器会将客户端 IP 地址存入到 X-Forwarded-For 首部。在 PHP 中,我们可以使用如下代码来获取:
$ip = !empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
需要注意,HTTP_X_FORWARDED_FOR 首部中的内容可能是一个 IP 地址列表,每个 IP 地址都是由逗号隔开的字符串形式。
有些情况下,我们可能需要获取更具体的客户端信息,例如主机名。在 PHP 中,我们可以使用 REMOTE_HOST 键值来获取客户端主机名。不过需要先开启 DNS 查询,否则 REMOTE_HOST 的值会是空的。我们可以使用如下代码来获取:
if(getenv('HTTP_CLIENT_IP')) {
$ip = getenv('HTTP_CLIENT_IP');
} elseif(getenv('HTTP_X_FORWARDED_FOR')) {
$ip = getenv('HTTP_X_FORWARDED_FOR');
} elseif(getenv('HTTP_X_FORWARDED')) {
$ip = getenv('HTTP_X_FORWARDED');
} elseif(getenv('HTTP_FORWARDED_FOR')) {
$ip = getenv('HTTP_FORWARDED_FOR');
} elseif(getenv('HTTP_FORWARDED')) {
$ip = getenv('HTTP_FORWARDED');
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}
if(getenv('REMOTE_HOST')) {
$hostname = getenv('REMOTE_HOST');
} else {
$hostname = gethostbyaddr($ip);
}
echo "客户端IP:" . $ip . ",客户端主机名:" . $hostname;
需要注意的是,如果开启了 DNS 查询,会对性能产生一定的影响,应谨慎使用。
除了 $_SERVER 数组外,PHP 也提供了一些内置函数,用于获取客户端的 IP 地址。这里介绍两个函数:getenv() 和 filter_input()。getenv() 函数可以获取环境变量,而 PHP 的 $_SERVER 数组也被视为一个环境变量集合。代码如下:
$ip = getenv('HTTP_CLIENT_IP') ? getenv('HTTP_CLIENT_IP') : getenv('HTTP_X_FORWARDED_FOR');
if (!$ip) {
$ip = filter_input(INPUT_SERVER,'REMOTE_ADDR', FILTER_VALIDATE_IP);
}
其中,filter_input() 函数可以过滤输入变量(例如 $_SERVER 数组中的值),从而保证获取的 IP 地址正确。
总结
本文分别介绍了通过 $_SERVER 数组、HTTP_X_FORWARDED_FOR 和 getenv() 函数来获取客户端 PHP 的 IP 地址的方式。需要注意的是,由于代理服务器和其他网络设备的存在,IP 地址和主机名的获取并不总是可靠的,开发者需要根据实际情况来选择合适的方式。