Setting Sun's Blog – 残阳 彪悍的人生不需要解释~~

13一/104

便捷的IP数据存储和查询

If you're new here, you may want to subscribe to my RSS feed. Thanks for visiting!

首先我们需要一个功能健全、容错率高的得到IP方法

    /**
     * 获取客户端IP
     *
     * @return string
     */
    function getClientIP()
    {
        if (isset($_SERVER))
        {
            if (isset($_SERVER["HTTP_X_FORWARDED_FOR"]))
            {
                $realip = $_SERVER["HTTP_X_FORWARDED_FOR"];
            }
            else if (isset($_SERVER["HTTP_CLIENT_IP"]))
            {
                $realip = $_SERVER["HTTP_CLIENT_IP"];
            }
            else
            {
                $realip = $_SERVER["REMOTE_ADDR"];
            }
        }
        else
        {
            if (getenv("HTTP_X_FORWARDED_FOR"))
            {
                $realip = getenv("HTTP_X_FORWARDED_FOR");
            }
            else if (getenv("HTTP_CLIENT_IP"))
            {
                $realip = getenv("HTTP_CLIENT_IP");
            }
            else
            {
                $realip = getenv("REMOTE_ADDR");
            }
        }

        return addslashes($realip);
    }

如果你只要知道IP地址那么以上代码就可以完成。存储即可。

如果你的需求想要知道这个IP的IP段列表或区域列表,那么恭喜你你杯具了。所以好的数据库设计还是必要的。

PHP自带的函数非常好用,ip2long,long2ip 可以自己去查下手册,保存成int整形入库。

//IP段
$sql = 'select * from `table` where `ip` >= ' . ip2long('10.4.0') . ' AND `ip` <= ' . ip2long('10.4.20.200');

对于没有函数支持的可以用下面方法实现。


function getIp2Long($ip)
{
        $ipList = explode('.', $ip);

        return 16777216 * intval($ipList[0]) + 65536 * intval($ipList[1]) + 256 * intval($ipList[2]) + intval($ipList[3]);
}

function getLong2Ip($ipLong)
{
        $ipList = array();

        for($i = 3 ; $i >= 0 ; $i--)
        {
                $ip = intval($ipLong / pow(256, $i));
                $ipList[] = $ip;
                $ipLong -= pow(256, $i) * $ip;
        }

        return implode('.', $ipList);
}

就先写到这里吧,纯真数据就是这个规则。