php 集合 $_SERVER['HTTP_CLIENT_IP'] 的值是否为空字符串?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7623187/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Will the value of a set $_SERVER['HTTP_CLIENT_IP'] be an empty string?
提问by Pacerier
I have a simple script which determines the user's IP address:
我有一个简单的脚本来确定用户的 IP 地址:
function GetIp(){
if (!empty($_SERVER['HTTP_CLIENT_IP']))
//check ip from share internet
{
$ip=$_SERVER['HTTP_CLIENT_IP'];
}
elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
//to check ip is pass from proxy
{
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
}
else
{
$ip=$_SERVER['REMOTE_ADDR'];
}
return $ip;
}
Now on the Net somewhere I saw someone using this script:
现在在网上的某个地方我看到有人使用这个脚本:
if (isset($_SERVER['HTTP_CLIENT_IP']) && $_SERVER['HTTP_CLIENT_IP'] != '')
$Ip = $_SERVER['HTTP_CLIENT_IP'];
elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] != '')
$Ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] != '')
$Ip = $_SERVER['REMOTE_ADDR'];
I was wondering if my implementation is broken.. Do I need to check if the value of $_SERVER['HTTP_CLIENT_IP'], $_SERVER['HTTP_X_FORWARDED_FOR'], or $_SERVER['REMOTE_ADDR']is empty? Or is it actually unnecessary to do so?
我在想,如果我在执行坏了..我是否需要检查的值$_SERVER['HTTP_CLIENT_IP'],$_SERVER['HTTP_X_FORWARDED_FOR']或者$_SERVER['REMOTE_ADDR']是空的?或者实际上没有必要这样做?
回答by Pekka
If the reason why you want to find out the client's IP address is really important, screw all this stuff.
如果您想找出客户端的 IP 地址的原因真的很重要,那就把所有这些都搞砸吧。
Any oneof these header values can be freely spoofed.
这些标头值中的任何一个都可以被随意欺骗。
REMOTE_ADDRis the only really reliable information, as it is transmitted to you by your web server that is handling the request. It can be theoretically falsified as well, but that is much, much harder than spoofing a header value, and an entirely different class of attack.
REMOTE_ADDR是唯一真正可靠的信息,因为它是由处理请求的 Web 服务器传输给您的。它在理论上也可以被伪造,但这比欺骗标头值要困难得多,而且是一种完全不同的攻击类别。
There are exceptions in very, very specific hosting environments behind reverse proxies. In those cases the person administering that proxy will be able to tell what header value you need to test for.
在反向代理背后的非常非常具体的托管环境中有例外。在这些情况下,管理该代理的人员将能够告诉您需要测试什么标头值。
回答by Kemo
From Kohanas' Request class:
来自 Kohanas 的请求类:
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])
AND isset($_SERVER['REMOTE_ADDR'])
AND in_array($_SERVER['REMOTE_ADDR'], Request::$trusted_proxies))
{
// Use the forwarded IP address, typically set when the
// client is using a proxy server.
// Format: "X-Forwarded-For: client1, proxy1, proxy2"
$client_ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
Request::$client_ip = array_shift($client_ips);
unset($client_ips);
}
elseif (isset($_SERVER['HTTP_CLIENT_IP'])
AND isset($_SERVER['REMOTE_ADDR'])
AND in_array($_SERVER['REMOTE_ADDR'], Request::$trusted_proxies))
{
// Use the forwarded IP address, typically set when the
// client is using a proxy server.
$client_ips = explode(',', $_SERVER['HTTP_CLIENT_IP']);
Request::$client_ip = array_shift($client_ips);
unset($client_ips);
}
elseif (isset($_SERVER['REMOTE_ADDR']))
{
// The remote IP address
Request::$client_ip = $_SERVER['REMOTE_ADDR'];
}
This is pretty much as good as it gets. Please note the Request::$trusted_proxiesarray and that your $ipvar is Request::$client_ipin this case.
这几乎和它得到的一样好。请注意Request::$trusted_proxies数组,并且您的$ipvarRequest::$client_ip在这种情况下。
回答by duskwuff -inactive-
Do not check any HTTP_*headers for the client IP unless you specifically know your application is configured behind a reverse proxy. Trusting the values of these headers unconditionally will allow users to spoof their IP address.
HTTP_*除非您明确知道您的应用程序是在反向代理之后配置的,否则不要检查客户端 IP 的任何标头。无条件信任这些标头的值将允许用户欺骗他们的 IP 地址。
The only $_SERVERfield containing a reliable value is REMOTE_ADDR.
$_SERVER包含可靠值的唯一字段是REMOTE_ADDR。
回答by klaustopher
The two things are practically identical.. In the script you found, the author is just doing a check if the element in the array is set before checking that it is non-empty.
这两件事实际上是相同的..在您找到的脚本中,作者只是在检查数组中的元素是否为非空之前先检查它是否已设置。
In regards to using the empty()-function instead of the comparison, check http://php.net/empty. Since you are dealing with a variable that is set by the environment and not a user input it doesn't matter which of the two options you choose. So your script should be perfectly fine
关于使用empty()-function 而不是比较,请检查http://php.net/empty。由于您正在处理由环境而不是用户输入设置的变量,因此您选择两个选项中的哪一个都没有关系。所以你的脚本应该没问题

