当前位置:编程学习 > 网站相关 >>

ShopEX后台查看用户IP对应地理位置


本文可以实现ShopEX在后台查看用户注册IP对应的地理位置信息,通过函数获取纯真IP数据库的信息并返回给模板,不需要写入数据库。获取纯真IP的函数修改自Discuz! 的源码。获取IP信息的代码稍加修改即可用作其它类型的网站,支持UTF-8及GBK编码。

修改前的效果:


\


(1)准备:
下载最新的纯真IP数据库 qqwry.dat
建立文件pure_get.php  代码如下:

[php]
<?php 
//包含ShopEX根目录下的配置文件 
include_once('../../../.././config/config.php'); 
 
 
//=================================== 
// 
// 功能:通过用户id获取ip 
// 参数:$mid 即是用户id 
// 
//=================================== 
 
 
function convertmid($mid){ 
 
    $ip_mid = $mid; 
 
    //连接数据库通过id获取ip 
    $ip_dbconn = mysql_connect(DB_HOST,DB_USER,DB_PASSWORD); 
 
    if($ip_dbconn){ 
        $ip_dbsel = mysql_select_db(DB_NAME,$ip_dbconn); 
        $ip_dbquery = 'SELECT reg_ip FROM `'.DB_PREFIX.'members` WHERE member_id='.$ip_mid; 
        $ip_dbresult = mysql_query($ip_dbquery, $ip_dbconn); 
        $ip_addr = mysql_result($ip_dbresult,0,0); 
 
        if(!$ip_dbresult){ 
            return 'NULL'; 
        } 
 
        return $ip_addr; 
 
    } 
     
    //关闭数据库 
    mysql_close($ip_dbconn); 

 
 
 
//=================================== 
// 
// 功能:IP地址获取真实地址函数 
// 参数:$ip - IP地址  $a1 - 是否为Linux系统  $a2 - 是否需要返回UTF-8编码 
// 
//=================================== 
 
 
function convertip($ip, $a1, $a2) { 
 
// 
$is_linux = $a1; 
$is_utf   = $a2; 
 
 
//纯真数据库文件绝对路径,linux下使用‘/’,windows下使用‘\’ 
if($is_linux){ 
    $dat_path = BASE_DIR.'/qqwry.dat';  
}else{ 
    $dat_path = BASE_DIR.'\qqwry.dat'; 

 
 
//检查IP地址格式 
if(!preg_match("/^\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}$/", $ip)){ 
    return 'IP 地址错误!'; 

 
 
//打开IP数据文件,如果提示'IP数据文件无法读取,请确保是正确的纯真IP库!',还有可能是文件位置的问题 
//所以请尽量吧qqwry.dat放在网站的根目录(注意,不是服务器根目录!) 
if(!$fd = @fopen($dat_path, 'rb')){ 
    return 'IP数据文件无法读取,请确保是正确的纯真IP库!'; 
}  
 
//分解IP进行运算,得出整形数 
$ip = explode('.', $ip); 
$ipNum = $ip[0] * 16777216 + $ip[1] * 65536 + $ip[2] * 256 + $ip[3]; //获取IP数据索引开始和结束位置 
$DataBegin = fread($fd, 4); 
$DataEnd = fread($fd, 4); 
$ipbegin = implode('', unpack('L', $DataBegin)); //unpack() 函数从二进制字符串对数据进行解包。unpack(format,data) L - unsigned long (always 32 bit, machine byte order) 
#$ipbegin 值如:5386001 
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; //使用二分查找法从索引记录中搜索匹配的IP记录 
$ip1num=''; $ip2num=''; $ipAddr1=''; $ipAddr2=''; 
while($ip1num>$ipNum || $ip2num<$ipNum) { 
$Middle= intval(($EndNum + $BeginNum) / 2); //偏移指针到索引位置读取4个字节 
fseek($fd, $ipbegin + 7 * $Middle); 
$ipData1 = fread($fd, 4); 
if(strlen($ipData1) < 4) { 
fclose($fd); 
return 'System Error'; 

//提取出来的数据转换成长整形,如果数据是负数则加上2的32次幂 
$ip1num = implode('', unpack('L', $ipData1)); 
if($ip1num < 0) $ip1num += pow(2, 32); 
 
//提取的长整型数大于我们IP地址则修改结束位置进行下一次循环 
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 {&nb

补充:Web开发 , 其他 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,