Check the geographical location corresponding to the user's IP in the ShopEX backend

This article can enable ShopEX to check the geographical location information corresponding to the user's registered IP in the background, obtain the information of the Innocence IP database through functions and return it to the template, without writing to the database. The function to obtain the innocent IP is modified from the source code of Discuz!. The code for obtaining IP information can be used for other types of websites with slight modifications, and supports UTF-8 and GBK encoding.


The effect before modification:



(1) Preparation:

Download the latest innocent IP database qqwry.dat

Create the file pure_get.php with the following code:


<?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 {
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';
} 

//如果需要UTF编码 则作出一些转换,否则返回GBK编码
if($is_utf){
	return iconv("gbk","utf-8",$ipaddr);
}else{
	return $ipaddr;
}

}



?>

(2) Upload files:

Place qqwry.dat in the ShopEX root directory and pure_get.php in the "shopex\core\admin\controller\member" directory


(3) Modify the code:

Open shopex\core\admin\controller\member\ctl.member.php and find the function function show_detail($nMId)

Inside the function add:

		// 修改:获取注册ip地址信息
		// 这里要注意函数 convertip 的参数一定要填对  不然会乱码
		include_once('pure_get.php');
		$ip_addr = convertmid($nMId); 
		$ip_location = convertip($ip_addr, 0, 1);
		$this->pagedata['ip_location'] = $ip_location;


Open the template shopex\core\admin\view\member\member_items.html and find <{$mem.reg_ip}>

Add at the end:

<label><{$ip_location}></label>

Note that $ip_location in member_items.html corresponds to pagedata[ip_location'] in the function show_detail. You can set some other values ​​first to test the display results.


(4) Test:

Check the effect in the background


(5) Description:

The function convertmid($mid) in pure_get.php is used to obtain the registered IP address of ShopEX using the user ID. This function is actually not very safe, but I currently don’t understand the code of ShopEX well enough and I can’t find a good method for the time being. It is a security measure to call the config file instead of directly using the database account and password.


If you can directly find the IP address variable, you can use convertip($ip, $a1, $a2) to access the innocence database and obtain the address information. Remember to add parameters, otherwise it will cause two errors: the IP database cannot be accessed or garbled characters are returned.


===================================

This article comes from: http://blog.csdn.net/zh405123507

tags:shopex IP innocence database qqwry


Guess you like

Origin blog.csdn.net/zh405123507/article/details/7424667