PHP:如何检查客户端是否是本地的?

时间:2011-08-09 15:59:17

标签: php networking ip

我需要检查文件是否“本地”打开(同一台机器或网络)。我正在使用:

<?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
}

但我不确定这是最好的方法。

这样做有什么更简单的方法?

3 个答案:

答案 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));
}