PHP:如何检查客户端是否是本地的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6999175/
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
PHP: how to check if the client is local?
提问by user852091
I need to check if a file is opened "locally" (same machine or network). I'm using:
我需要检查文件是否在“本地”(同一台机器或网络)打开。我正在使用:
<?php
if ((substr($_SERVER['REMOTE_ADDR'],0,8) == "192.168.") || ($_SERVER['REMOTE_ADDR'] == "127.0.0.1")) {
// client is local
} else {
// client is not local
}
But I'm not sure this is the best way.
但我不确定这是最好的方法。
What is a more foolproof way of doing this?
这样做的更万无一失的方法是什么?
采纳答案by Uffe
"Foolproof," as always, can be tricky.
“万无一失”,一如既往,可能很棘手。
If we do restrict ourselves to IPv4, then checking for "127.0.0.1" takes care of the localhost case, but checking against "192.168." is plain wrong - it will only work if the script is being run on a server which happens to be on the 192.168 network, using a 16-bit subnet mask.
如果我们确实将自己限制为 IPv4,那么检查“127.0.0.1”会处理本地主机情况,但会检查“192.168”。完全错误 - 只有在使用 16 位子网掩码的恰好位于 192.168 网络上的服务器上运行脚本时,它才会起作用。
Checking $_SERVER['REMOTE_ADDR'] against $_SERVER['SERVER_ADDR'] would be a better bet. This still doesn't take care of the case of a multi-homed host (ie one which has several IP addresses in addition to 127.0.0.1), though.
检查 $_SERVER['REMOTE_ADDR'] 对 $_SERVER['SERVER_ADDR'] 将是一个更好的选择。但是,这仍然无法解决多宿主主机(即除了 127.0.0.1 之外还有多个 IP 地址的主机)的情况。
In order to catch all same-network cases, you'd need to check the combination of SERVER_ADDR and subnet mask against REMOTE_ADDR, but the subnet mask isn't available in $_SERVER.
为了捕获所有相同网络的情况,您需要针对 REMOTE_ADDR 检查 SERVER_ADDR 和子网掩码的组合,但子网掩码在 $_SERVER 中不可用。
BUT I found a function which does pretty much what you want here. It's a couple of screens down and it's called clientInSameSubnet. Not my code, but looks right.
但是我在这里找到了一个功能,它几乎可以满足您的需求。这是几个屏幕,它被称为clientInSameSubnet。不是我的代码,但看起来不错。
回答by Miguel Trias
What Friek said is true, but provided that you know how to get the real client's IP, you can tell if it's a local address using PHP filters:
Friek 说的是真的,但是如果您知道如何获取真实客户端的 IP,您就可以使用PHP 过滤器判断它是否是本地地址:
if ( ! filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) )
{
// is a local ip address
}
回答by Troy Alford
In case anyone has trouble finding the above code, suggested by @Uffe, I've included it below:
如果有人找不到@Uffe 建议的上述代码,我将其包含在下面:
<?php
/**
* Check if a client IP is in our Server subnet
*
* @param string $client_ip
* @param string $server_ip
* @return boolean
*/
function clientInSameSubnet($client_ip=false,$server_ip=false) {
if (!$client_ip)
$client_ip = $_SERVER['REMOTE_ADDR'];
if (!$server_ip)
$server_ip = $_SERVER['SERVER_ADDR'];
// Extract broadcast and netmask from ifconfig
if (!($p = popen("ifconfig","r"))) return false;
$out = "";
while(!feof($p))
$out .= fread($p,1024);
fclose($p);
// This is to avoid wrapping.
$match = "/^.*".$server_ip;
$match .= ".*Bcast:(\d{1,3}\.\d{1,3}i\.\d{1,3}\.\d{1,3}).*";
$match .= "Mask:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/im";
if (!preg_match($match,$out,$regs))
return false;
$bcast = ip2long($regs[1]);
$smask = ip2long($regs[2]);
$ipadr = ip2long($client_ip);
$nmask = $bcast & $smask;
return (($ipadr & $smask) == ($nmask & $smask));
}