我需要检查文件是否“本地”打开(同一台机器或网络)。我正在使用:
<?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
}
但我不确定这是最好的方法。
这样做有什么更简单的方法?
答案 0 :(得分:44)
Friek说的是真的,但如果您知道如何获取真实客户的IP,您可以使用PHP filters判断它是否是本地地址:
if ( ! filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) )
{
// is a local ip address
}
答案 1 :(得分:9)
如果我们将自己限制为IPv4,那么检查“127.0.0.1”会处理localhost情况,但会检查“192.168”。是完全错误的 - 只有在使用16位子网掩码的192.168网络上的服务器上运行脚本时,它才有效。
对$ _SERVER ['SERVER_ADDR']检查$ _SERVER ['REMOTE_ADDR']将是一个更好的选择。但是,这仍然没有考虑多宿主主机(即除了127.0.0.1之外还有几个IP地址的主机)的情况。
为了捕获所有相同的网络情况,您需要针对REMOTE_ADDR检查SERVER_ADDR和子网掩码的组合,但子网掩码在$ _SERVER中不可用。
但是我发现了一个能够完成你想要的功能的here。这是几个屏幕,它被称为clientInSameSubnet。不是我的代码,但看起来是正确的。
答案 2 :(得分:3)
如果有人在找到上述代码时遇到问题,@ 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));
}