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

13一/104

便捷的IP数据存储和查询

首先我们需要一个功能健全、容错率高的得到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);
}

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

随机日志

标签:ip, ip2long, long2ip

相关日志

关于 Setting Sun

我表示无节操,万物皆可控!
评论 (4) 引用 (0)
  1. ip2long在32位与64位系统里部分结果不同。比如200.200.200.200这种。long2ip不影响。

    [回复]

    Setting Sun 回复:

    @echo, 事实证明如果用自己写的函数getIp2Long,就不会有负数的问题

    ip2long算的数,大于了2^32所以就出现负数了

    [回复]

  2. 事实上,ip2long很可能会溢出而造成取回来的long是负数。因此还是要注意一下的。(其实大概就是echo说的32位与64的的不同了。没测试是不是int溢出。)

    [回复]

    Setting Sun 回复:

    @膘叔, 确实是int溢出了

    [回复]


发表评论


还没有引用.