Gimhoy's Blog

WordPress获取真实IP,以及将IP转换成归属地

本文最后更新于2013年8月15日,已超过三年没有更新,如果文章内容失效,请反馈给我们,谢谢!

 

WordPress获取真实IP

之前写《WordPress后台登陆邮件提醒》的时候,用到了$_SERVER['REMOTE_ADDR']来获取访客的IP地址,麦田一根葱提醒说这样获取的不是真实的地址,根据他的代码改了一下,让WordPress取得真实IP。当然,在很多情况下,$_SERVER['REMOTE_ADDR']取得的就是真实地址了~~

代码:

/**
 * 获取用户真实IP
 * Modified Gimhoy (http://blog.gimhoy.com)
 */
function getIP()
{
    static $realIP;
    if (isset($_SERVER)){
        if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])){
            $realIP = explode(',', $_SERVER["HTTP_X_FORWARDED_FOR"]);
	    $realIP = $realIP[0];
        } 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");
        }
    }
    $_SERVER['REMOTE_ADDR'] = $realIP;
    //return $realIP;
}
add_action( 'init', 'getIP' );

丢进当前主题的functions.php中即可~

 

IP转换为归属地

之前也有网友问如何将IP转换成归属地,这个有几种方法,简单介绍如下:

1.使用纯真IP数据库

纯真IP数据库也就是QQ IP数据库纯真版,收集了包括中国电信、中国网通、长城宽带、网通宽带、聚友宽带等 ISP 的最新准确 IP 地址数据。包括最全的网吧数据,IP数据库每5天更新一次。

使用方法:下载QQ IP数据库纯真版,百度一下就能找到了~将其中的QQWry.Dat放入主题目录下。然后在当前主题下的functions.php中丢入以下代码

//IP转地址
function convertip($ip) {
    $dat_path = TEMPLATEPATH.'/QQWry.Dat';
    if(!$fd = @fopen($dat_path, 'rb')){
        return 'IP date file not exists or access denied';
    }
    $ip = explode('.', $ip);
    $ipNum = $ip[0] * 16777216 + $ip[1] * 65536 + $ip[2] * 256 + $ip[3];
    $DataBegin = fread($fd, 4);
    $DataEnd = fread($fd, 4);
    $ipbegin = implode('', unpack('L', $DataBegin));
    if($ipbegin < 0) $ipbegin += pow(2, 32);
    $ipend = implode('', unpack('L', $DataEnd));
    if($ipend < 0) $ipend += pow(2, 32);
    $ipAllNum = ($ipend - $ipbegin) / 7 + 1;
    $BeginNum = 0;
    $EndNum = $ipAllNum;
    while($ip1num>$ipNum || $ip2num<$ipNum) {
        $Middle= intval(($EndNum + $BeginNum) / 2);
        fseek($fd, $ipbegin + 7 * $Middle);
        $ipData1 = fread($fd, 4);
        if(strlen($ipData1) < 4) {
            fclose($fd);
            return 'System Error';
        }
        $ip1num = implode('', unpack('L', $ipData1));
        if($ip1num < 0) $ip1num += pow(2, 32);
        if($ip1num > $ipNum) {
            $EndNum = $Middle;
            continue;
        }
        $DataSeek = fread($fd, 3);
        if(strlen($DataSeek) < 3) {
            fclose($fd);
            return 'System Error';
        }
        $DataSeek = implode('', unpack('L', $DataSeek.chr(0)));
        fseek($fd, $DataSeek);
        $ipData2 = fread($fd, 4);
        if(strlen($ipData2) < 4) {
            fclose($fd);
            return 'System Error';
        }
        $ip2num = implode('', unpack('L', $ipData2));
        if($ip2num < 0) $ip2num += pow(2, 32);
        if($ip2num < $ipNum) {
            if($Middle == $BeginNum) {
                fclose($fd);
                return 'Unknown';
            }
            $BeginNum = $Middle;
        }
    }
    $ipFlag = fread($fd, 1);
    if($ipFlag == chr(1)) {
        $ipSeek = fread($fd, 3);
        if(strlen($ipSeek) < 3) {
            fclose($fd);
            return 'System Error';
        }
        $ipSeek = implode('', unpack('L', $ipSeek.chr(0)));
        fseek($fd, $ipSeek);
        $ipFlag = fread($fd, 1);
    }
    if($ipFlag == chr(2)) {
        $AddrSeek = fread($fd, 3);
        if(strlen($AddrSeek) < 3) {
            fclose($fd);
            return 'System Error';
        }
        $ipFlag = fread($fd, 1);
        if($ipFlag == chr(2)) {
            $AddrSeek2 = fread($fd, 3);
            if(strlen($AddrSeek2) < 3) {
                fclose($fd);
                return 'System Error';
            }
            $AddrSeek2 = implode('', unpack('L', $AddrSeek2.chr(0)));
            fseek($fd, $AddrSeek2);
        } else {
            fseek($fd, -1, SEEK_CUR);
        }
        while(($char = fread($fd, 1)) != chr(0))
        $ipAddr2 .= $char;
        $AddrSeek = implode('', unpack('L', $AddrSeek.chr(0)));
        fseek($fd, $AddrSeek);
        while(($char = fread($fd, 1)) != chr(0))
        $ipAddr1 .= $char;
    } else {
        fseek($fd, -1, SEEK_CUR);
        while(($char = fread($fd, 1)) != chr(0))
        $ipAddr1 .= $char;

        $ipFlag = fread($fd, 1);
        if($ipFlag == chr(2)) {
            $AddrSeek2 = fread($fd, 3);
            if(strlen($AddrSeek2) < 3) {
                fclose($fd);
                return 'System Error';
            }
            $AddrSeek2 = implode('', unpack('L', $AddrSeek2.chr(0)));
            fseek($fd, $AddrSeek2);
        } else {
            fseek($fd, -1, SEEK_CUR);
        }
        while(($char = fread($fd, 1)) != chr(0)){
            $ipAddr2 .= $char;
        }
    }
    fclose($fd);
    if(preg_match('/http/i', $ipAddr2)) {
        $ipAddr2 = '';
    }
    $ipaddr = "$ipAddr1 $ipAddr2";
    $ipaddr = preg_replace('/CZ88.Net/is', '', $ipaddr);
    $ipaddr = preg_replace('/^s*/is', '', $ipaddr);
    $ipaddr = preg_replace('/s*$/is', '', $ipaddr);
    if(preg_match('/http/i', $ipaddr) || $ipaddr == '') {
        $ipaddr = 'Unknown';
    }
    $ipaddr = iconv('gbk', 'utf-8//IGNORE', $ipaddr); 
    if( $ipaddr != '  ' )
        return $ipaddr;
    else
        $ipaddr = '地址未知!火星来客?';
        return $ipaddr;
}

使用的时候调用这个函数即可。

2.采用IP查询API接口

国内不少互联网公司例如腾讯、新浪以及淘宝都有IP查询接口,直接调用查询即可。

(1)腾讯IP分享计划

/*
*根据腾讯IP分享计划的地址获取IP所在地,比较精确
*/
function getIPLoc_QQ($ip1){
$url = 'http://ip.qq.com/cgi-bin/searchip?searchip1='.$ip1;
$ch = curl_init($url);
curl_setopt($ch,CURLOPT_ENCODING ,'gb2312');
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) ; // 获取数据返回
$result = curl_exec($ch);
$result = mb_convert_encoding($result, "utf-8", "gb2312"); // 编码转换,否则乱码
curl_close($ch);
preg_match("@<span>(.*)</span></p>@iU",$result,$ipArray);
$loc = $ipArray[1];
return $loc;
}

(2)新浪IP查询接口

/*
*根据新浪IP查询接口获取IP所在地
*/
function getIPLoc_sina($ip1){
$url = 'http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip='.$ip1;
$ch = curl_init($url);
//curl_setopt($ch,CURLOPT_ENCODING ,'utf8');
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) ; // 获取数据返回
$location = curl_exec($ch);
$location = json_decode($location);
curl_close($ch);
 
$loc = "";
if($location===FALSE) return "";
if (emptyempty($location->desc)) {
$loc = $location->province.$location->city.$location->district.$location->isp;
}else{
$loc = $location->desc;
}
return $loc;
}

以上两个代码来自麦田一根葱

(3)使用淘宝IP接口

/**
 * 根据淘宝IP查询接口获取IP所在地
 */
function getCity($ip)
{
	$url="http://ip.taobao.com/service/getIpInfo.php?ip=".$ip;
	$ip=json_decode(file_get_contents($url));	
	if((string)$ip->code=='1'){
	   return false;
 	}
 	$data = (array)$ip->data;
	return $data;	
}

 

应用

这篇文章太长了。。下一篇文章讲应用=。= 应用见下面的文章:

将IP转换成归属地在WordPress中的应用:在评论列表/后台评论列表/评论通知邮件中显示评论者IP所在地

将IP转换成归属地在WordPress中的应用:登陆者IP所在地



免费获得每月10G空间+10G免费流量
  • Comment (16)
  • Trackback (2)
  • 5555555555MozillaWindowsChina2014/06/09 02:14@Ta

    🙄

    签到成功!签到时间:‎02‎:‎06‎:‎55,每日打卡,生活更精彩哦~

    #7
  • ycvvGoogle ChromeWindowsChina2013/08/25 23:10@Ta

    反馈下你的主题,我用GOOGLE 看你的博客,一按返回你右边的侧边栏会跑到左边去,不过刷新下就好了
    还有你的代码想用啊,但是复制很蛋疼有木有....

    #6
    • GimhoyGoogle ChromeWindowsChina2013/08/26 06:57@Ta

      主题的问题我已经发现了,之后会抽空修改。代码没找着好用的插件,暂时只能这样了。。感谢支持~

  • 1234Google ChromeWindowsChina2013/08/15 18:08@Ta

    请教下博主,我用了获取真实ip这个代码。但是在wordpress后台评论里面所看到的ip和我收到邮件中的ip不一样啊。

    #5
    • GimhoyGoogle ChromeWindowsChina2013/08/15 23:08@Ta

      @1234:可能是你用了两个不同的方法获取的IP

      • 1234Google ChromeWindowsChina2013/08/16 08:19@Ta

        @Gimhoy:谢谢博主,还真是的。主题自带了获取ip的代码,不过这个代码有些坑爹了,获取不到真实的ip。我得去反馈反馈,建议作者用用你的代码。

  • root9000Mozilla FirefoxWindowsChina2013/07/19 09:15@Ta

    晕。一复制格式全乱了。。。

    #4
    • GimhoyGoogle ChromeWindowsChina2013/07/20 16:07@Ta

      @root9000:不客气~复制怎么会乱格式呢?用了插件显示代码的。。

  • root9000Mozilla FirefoxWindowsChina2013/07/19 08:52@Ta

    不错不错,用上了。谢谢博主

    #3
  • tennfyGoogle ChromeWindowsChina2013/07/18 16:45@Ta

    主题真不错

    #2
  • 麦田一根葱Google ChromeWindowsChina2013/07/18 13:17@Ta

    :mrgreen:代码狂....居然丢进functions.php里,学习了

    #1