| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 | 
							- <?php 
 
- /**
 
-  * ip_area.class.php 根据ip地址获取ip所在地区的类
 
-  *
 
-  * @copyright			(C) 2005-2010 PHPCMS
 
-  * @license				http://www.phpcms.cn/license/
 
-  * @lastmodify			2010-6-7
 
-  */
 
- class ip_area {
 
- 	public $fp = NULL;		//定义文件指针
 
- 	public $func;			//处理的方法
 
- 	private $offset;		
 
- 	private $index;
 
- 	
 
- 	/**
 
-  	 * 构造函数
 
-  	 * 
 
-  	 */
 
- 	public function __construct() {
 
- 		if(@file_exists(PC_PATH.DIRECTORY_SEPARATOR.'libs'.DIRECTORY_SEPARATOR.'data'.DIRECTORY_SEPARATOR.'ipdata'.DIRECTORY_SEPARATOR.'mini.Dat')) {
 
- 			$this->func = 'data_mini';
 
- 			$this->fp = @fopen(PC_PATH.DIRECTORY_SEPARATOR.'libs'.DIRECTORY_SEPARATOR.'data'.DIRECTORY_SEPARATOR.'ipdata'.DIRECTORY_SEPARATOR.'mini.Dat', 'rb');
 
- 			$this->offset = unpack('Nlen', fread($this->fp, 4));
 
- 			$this->index  = fread($this->fp, $this->offset['len'] - 4);
 
- 		} elseif(@file_exists(PC_PATH.DIRECTORY_SEPARATOR.'libs'.DIRECTORY_SEPARATOR.'data'.DIRECTORY_SEPARATOR.'ipdata'.DIRECTORY_SEPARATOR.'QQWry.Dat')) {
 
- 			$this->func = 'data_full';
 
- 			$this->fp = @fopen(PC_PATH.DIRECTORY_SEPARATOR.'libs'.DIRECTORY_SEPARATOR.'data'.DIRECTORY_SEPARATOR.'ipdata'.DIRECTORY_SEPARATOR.'QQWry.Dat', 'rb');
 
- 		} elseif(@file_exists(PC_PATH.DIRECTORY_SEPARATOR.'libs'.DIRECTORY_SEPARATOR.'data'.DIRECTORY_SEPARATOR.'ipdata'.DIRECTORY_SEPARATOR.'qqwry.dat')) {
 
- 			$this->func = 'data_full';
 
- 			$this->fp = @fopen(PC_PATH.DIRECTORY_SEPARATOR.'libs'.DIRECTORY_SEPARATOR.'data'.DIRECTORY_SEPARATOR.'ipdata'.DIRECTORY_SEPARATOR.'qqwry.dat', 'rb');
 
- 		}
 
- 	}
 
- 	/**
 
-  	 * 取得地区名
 
-  	 * @param  string $ip IP地址
 
-  	 * @ return string/null
 
-  	 */
 
- 	public function get($ip) {
 
- 		$return = '';
 
- 		if(preg_match("/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/", $ip)) {
 
- 			$iparray = explode('.', $ip);
 
- 			if($iparray[0] == 10 || $iparray[0] == 127 || ($iparray[0] == 192 && $iparray[1] == 168) || ($iparray[0] == 172 && ($iparray[1] >= 16 && $iparray[1] <= 31))) {
 
- 				$return = 'LAN';
 
- 			} elseif($iparray[0] > 255 || $iparray[1] > 255 || $iparray[2] > 255 || $iparray[3] > 255) {
 
- 				$return = 'Invalid IP Address';
 
- 			} else {
 
- 				$return = $this->func ? $this->{$this->func}($ip) : '';
 
- 				if(strpos($return, ' ') !== false) $return = substr($return, 0, strpos($return,' '));
 
- 			}
 
- 			if(strtolower(pc_base::load_config('system', 'charset')) == 'utf-8') $return = iconv('gbk', 'utf-8', $return);
 
- 		}
 
- 		return $return;
 
- 	}
 
- 	
 
- 	/**
 
- 	* 通过外部接口方式获取详细地址信息
 
- 	* @return $localinfo province 省份 city城市  sp网络 提供商  pinyin拼音
 
- 	*/
 
- 	public function getcitybyapi($ip) {
 
- 		$api_url = $localinfo = '';
 
- 		$xml = pc_base::load_sys_class('xml');
 
- 		pc_base::load_sys_func('iconv');
 
- 		$api_url = 'http://ipquery.sdo.com/getipinfo.php?ip='.$ip;
 
- 		$data = $xml->xml_unserialize(@file_get_contents($api_url));
 
- 		if (CHARSET == 'gbk') {
 
- 			$data = !empty($data) ? array_iconv($data, 'utf-8', 'gbk') : array();
 
- 		}		
 
- 		if($data['ip']['result']) {
 
- 			$localinfo['province'] = $data['ip']['country'];
 
- 			$localinfo['city'] = $data['ip']['city'];
 
- 			$localinfo['sp'] = $data['ip']['sp'];		
 
- 			//$name = strtolower(CHARSET) == 'gbk' ? $localinfo['city'] : iconv(CHARSET,'gbk',$localinfo['city']);
 
- 			$name = str_replace(L('city'),'',$localinfo['city']);
 
- 			$letters = gbk_to_pinyin($name);	
 
- 			$localinfo['pinyin'] =strtolower(implode('', $letters));		
 
- 		}		
 
- 		return $localinfo;		
 
- 	}
 
- 	
 
- 	/**
 
- 	*获取城市名称
 
- 	*/
 
- 	public function getcity($ip) {
 
- 		$localinfo = '';
 
- 		$address = $this->get($ip);
 
- 		if(strpos($address,L('province'))!== false && strpos($address,L('city'))!== false){
 
- 			$address = explode(L('province'), $address);
 
- 			$address=$address[1];
 
- 		}
 
- 		$address = str_replace(L('city'),'',$address);
 
- 		$localinfo['city']= trim($address);
 
- 		$name = CHARSET == 'gbk' ? $localinfo['city'] : iconv('utf-8','gbk',$localinfo['city']);
 
- 		$name = str_replace(L('city'),'',$name);
 
- 		$letters = gbk_to_pinyin($name);	
 
- 		$localinfo['pinyin'] =strtolower(implode('', $letters));
 
- 		return $localinfo;
 
- 	}
 
- 	/**
 
-  	 * 使用mini.Dat ip数据包获取地区
 
-  	 * @param  string $ip IP地址
 
-  	 * @ return string/null
 
-  	 */
 
- 	private function data_mini($ip) {
 
- 		$ipdot = explode('.', $ip);
 
- 		$ipdot[0] = (int)$ipdot[0];
 
- 		$ipdot[1] = (int)$ipdot[1];
 
- 		$ip    = pack('N', ip2long($ip));
 
- 		$length = $this->offset['len'] - 1028;
 
- 		$start  = unpack('Vlen', $this->index[$ipdot[0] * 4] . $this->index[$ipdot[0] * 4 + 1] . $this->index[$ipdot[0] * 4 + 2] . $this->index[$ipdot[0] * 4 + 3]);
 
- 		for($start = $start['len'] * 8 + 1024; $start < $length; $start += 8) {
 
- 			if($this->index{$start} . $this->index{$start + 1} . $this->index{$start + 2} . $this->index{$start + 3} >= $ip) {
 
- 				$this->index_offset = unpack('Vlen', $this->index{$start + 4} . $this->index{$start + 5} . $this->index{$start + 6} . "\x0");
 
- 				$this->index_length = unpack('Clen', $this->index{$start + 7});
 
- 				break;
 
- 			}
 
- 		}
 
- 		fseek($this->fp, $this->offset['len'] + $this->index_offset['len'] - 1024);
 
- 		if($this->index_length['len']) {
 
- 			return str_replace('- ', '', fread($this->fp, $this->index_length['len']));
 
- 		} else {
 
- 			return 'Unknown';
 
- 		}
 
- 	}
 
- 	
 
- 	/**
 
-  	 * 使用QQWry.Dat ip数据包获取地区
 
-  	 * @param  string $ip IP地址
 
-  	 * @ return string/null
 
-  	 */
 
- 	private function data_full($ip) {
 
- 		rewind($this->fp);
 
- 		$ip = explode('.', $ip);
 
- 		$ipNum = $ip[0] * 16777216 + $ip[1] * 65536 + $ip[2] * 256 + $ip[3];
 
- 		if(!($DataBegin = fread($this->fp, 4)) || !($DataEnd = fread($this->fp, 4)) ) return;
 
- 		@$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 = $ip2num = $ip1num = 0;
 
- 		$ipAddr1 = $ipAddr2 = '';
 
- 		$EndNum = $ipAllNum;
 
- 		while($ip1num > $ipNum || $ip2num < $ipNum) {
 
- 			$Middle= intval(($EndNum + $BeginNum) / 2);
 
- 			fseek($this->fp, $ipbegin + 7 * $Middle);
 
- 			$ipData1 = fread($this->fp, 4);
 
- 			if(strlen($ipData1) < 4) {
 
- 				fclose($this->fp);
 
- 				return 'System Error';
 
- 			}
 
- 			$ip1num = implode('', unpack('L', $ipData1));
 
- 			if($ip1num < 0) $ip1num += pow(2, 32);
 
- 			if($ip1num > $ipNum) {
 
- 				$EndNum = $Middle;
 
- 				continue;
 
- 			}
 
- 			$DataSeek = fread($this->fp, 3);
 
- 			if(strlen($DataSeek) < 3) {
 
- 				fclose($this->fp);
 
- 				return 'System Error';
 
- 			}
 
- 			$DataSeek = implode('', unpack('L', $DataSeek.chr(0)));
 
- 			fseek($this->fp, $DataSeek);
 
- 			$ipData2 = fread($this->fp, 4);
 
- 			if(strlen($ipData2) < 4) {
 
- 				fclose($this->fp);
 
- 				return 'System Error';
 
- 			}
 
- 			$ip2num = implode('', unpack('L', $ipData2));
 
- 			if($ip2num < 0) $ip2num += pow(2, 32);
 
- 			if($ip2num < $ipNum) {
 
- 				if($Middle == $BeginNum) {
 
- 					fclose($this->fp);
 
- 					return 'Unknown';
 
- 				}
 
- 				$BeginNum = $Middle;
 
- 			}
 
- 		}
 
- 		$ipFlag = fread($this->fp, 1);
 
- 		if($ipFlag == chr(1)) {
 
- 			$ipSeek = fread($this->fp, 3);
 
- 			if(strlen($ipSeek) < 3) {
 
- 				fclose($this->fp);
 
- 				return 'System Error';
 
- 			}
 
- 			$ipSeek = implode('', unpack('L', $ipSeek.chr(0)));
 
- 			fseek($this->fp, $ipSeek);
 
- 			$ipFlag = fread($this->fp, 1);
 
- 		}
 
- 		if($ipFlag == chr(2)) {
 
- 			$AddrSeek = fread($this->fp, 3);
 
- 			if(strlen($AddrSeek) < 3) {
 
- 				fclose($this->fp);
 
- 				return 'System Error';
 
- 			}
 
- 			$ipFlag = fread($this->fp, 1);
 
- 			if($ipFlag == chr(2)) {
 
- 				$AddrSeek2 = fread($this->fp, 3);
 
- 				if(strlen($AddrSeek2) < 3) {
 
- 					fclose($this->fp);
 
- 					return 'System Error';
 
- 				}
 
- 				$AddrSeek2 = implode('', unpack('L', $AddrSeek2.chr(0)));
 
- 				fseek($this->fp, $AddrSeek2);
 
- 			} else {
 
- 				fseek($this->fp, -1, SEEK_CUR);
 
- 			}
 
- 			while(($char = fread($this->fp, 1)) != chr(0))
 
- 			$ipAddr2 .= $char;
 
- 			$AddrSeek = implode('', unpack('L', $AddrSeek.chr(0)));
 
- 			fseek($this->fp, $AddrSeek);
 
- 			while(($char = fread($this->fp, 1)) != chr(0))
 
- 			$ipAddr1 .= $char;
 
- 		} else {
 
- 			fseek($this->fp, -1, SEEK_CUR);
 
- 			while(($char = fread($this->fp, 1)) != chr(0))
 
- 			$ipAddr1 .= $char;
 
- 			$ipFlag = fread($this->fp, 1);
 
- 			if($ipFlag == chr(2)) {
 
- 				$AddrSeek2 = fread($this->fp, 3);
 
- 				if(strlen($AddrSeek2) < 3) {
 
- 					fclose($this->fp);
 
- 					return 'System Error';
 
- 				}
 
- 				$AddrSeek2 = implode('', unpack('L', $AddrSeek2.chr(0)));
 
- 				fseek($this->fp, $AddrSeek2);
 
- 			} else {
 
- 				fseek($this->fp, -1, SEEK_CUR);
 
- 			}
 
- 			while(($char = fread($this->fp, 1)) != chr(0))
 
- 			$ipAddr2 .= $char;
 
- 		}
 
- 		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';
 
- 		return ''.$ipaddr;
 
- 	}
 
- 	private function close() {
 
- 		@fclose($this->fp);
 
- 	}
 
- }
 
- ?>
 
 
  |