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开发 , 其他 ,