ShopEX バックエンドでユーザーの IP に対応する地理的位置を確認します。

この記事により、ShopEX はデータベースに書き込むことなく、ユーザーの登録 IP に対応する地理的位置情報をバックグラウンドで確認し、関数を通じて Innocence IP データベースの情報を取得してテンプレートに返すことができるようになります。無害な IP を取得する関数は、Discuz! のソース コードから変更されています。IP 情報を取得するコードは、少し変更するだけで他の種類の Web サイトに使用でき、UTF-8 および GBK エンコードをサポートしています。


修正前の効果:



(1) 準備:

最新の無害な IP データベース qqwry.dat をダウンロードします。

次のコードを使用してファイル pure_get.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 {
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) ファイルをアップロードする:

qqwry.dat を ShopEX ルート ディレクトリに配置し、pure_get.php を "shopex\core\admin\controller\member" ディレクトリに配置します。


(3) コードを変更します。

shopex\core\admin\controller\member\ctl.member.php を開き、関数 function show_detail($nMId) を見つけます。

関数内に以下を追加します。

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


テンプレート shopex\core\admin\view\member\member_items.html を開き、<{$mem.reg_ip}> を見つけます。

最後に次のように追加します。

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

member_items.html の $ip_location は関数 show_detail の pagedata[ip_location'] に対応することに注意してください。最初に他の値を設定して表示結果をテストすることができます。


(4) テスト:

バックグラウンドで効果を確認する


(5) 説明:

pure_get.php の関数 Convertmid($mid) は、ユーザー ID を使用して ShopEX の登録 IP アドレスを取得するために使用されます。この関数は実際にはあまり安全ではありませんが、現時点では ShopEX のコードを十分に理解していないので、当面は良い方法が見つかりません。データベース アカウントとパスワードを直接使用するのではなく、構成ファイルを呼び出すのはセキュリティ対策です。


IP アドレス変数を直接見つけることができる場合は、convertip($ip, $a1, $a2) を使用して innocence データベースにアクセスし、アドレス情報を取得できます。忘れずにパラメータを追加してください。追加しないと、IP データベースにアクセスできないか、文字化けした文字が返されるという 2 つのエラーが発生します。


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

この記事の引用元: http://blog.csdn.net/zh405123507

タグ:shopex IP 無罪データベース qqwry


おすすめ

転載: blog.csdn.net/zh405123507/article/details/7424667