Home Backend Development PHP Tutorial php 相仿腾讯的IP库

php 相仿腾讯的IP库

Jun 13, 2016 pm 01:15 PM
gt location return this

php 类似腾讯的IP库
$IpLocation = new IpLocation('ipData/QQWry.Dat'); 
$ipInfo=$IpLocation->getlocation($ip);
print_r($ipInfo);
注意获取的数据编码为 gbk


class IpLocation 
{
	/**
	 * QQWry.Dat文件指针
	 * @var resource
	 */
	var $fp;
	
	/**
	 * 第一条IP记录的偏移地址
	 * @var int
	 */
	var $firstip;
	
	/**
	 * 最后一条IP记录的偏移地址
	 * @var int
	 */
	var $lastip;
	
	/**
	 * IP记录的总条数(不包含版本信息记录)
	 * @var int
	 */
	var $totalip;
    
	/**
	 * 返回读取的长整型数
	 * @access private
	 * @return int
	 */
	function getlong() 
	{
		$result = unpack('Vlong', fread($this->fp, 4));	//将读取的little-endian编码的4个字节转化为长整型数
		return $result['long'];
	}
    
	/**
	* 返回读取的3个字节的长整型数
	* @access private
	* @return int
	*/
	function getlong3() 
	{
		$result = unpack('Vlong', fread($this->fp, 3).chr(0));	//将读取的little-endian编码的3个字节转化为长整型数
		return $result['long'];
	}
    
	/**
	* 返回压缩后可进行比较的IP地址
	* @access private
	* @param string $ip
	* @return string
	*/
	function packip($ip) 
	{
		// 将IP地址转化为长整型数,如果在PHP5中,IP地址错误,则返回False,
		// 这时intval将Flase转化为整数-1,之后压缩成big-endian编码的字符串
		return pack('N', intval(ip2long($ip)));			//intaval 获取变量的整数值
	}
    
	/**
	* 返回读取的字符串
	* @access private
	* @param string $data
	* @return string
	*/
	function getstring($data = "") 
	{
		$char = fread($this->fp, 1);
		while (ord($char) > 0)					// 字符串按照C格式保存,以\0结束 ord()得到字符的ASCII码
		{
			$data .= $char;				// 将读取的字符连接到给定字符串之后
			$char = fread($this->fp, 1);
		}
		return $data;
	}
    
	/**
	* 返回地区信息
	* @access private
	* @return string
	*/
	function getarea() 
	{
		$byte = fread($this->fp, 1);				// 标志字节
		switch (ord($byte)) {
			case 0:						// 没有区域信息
				$area = "";
				break;
			case 1:
			case 2:						// 标志字节为1或2,表示区域信息被重定向
				fseek($this->fp, $this->getlong3());
				$area = $this->getstring();
				break;
			default:					// 否则,表示区域信息没有被重定向
				$area = $this->getstring($byte);
				break;
		}
		return $area;
	}
    
	/**
	* 根据所给 IP 地址或域名返回所在地区信息
	* @access public
	* @param string $ip
	* @return array
	*/
	function getlocation($ip = '') 
	{
		if (!$this->fp) return null;				// 如果数据文件没有被正确打开,则直接返回空
		if($ip == '') $ip = $this->clientIp();
		$location['ip'] = gethostbyname($ip);			// 将输入的域名转化为IP地址
		$ip = $this->packip($location['ip']);			// 将输入的IP地址转化为可比较的IP地址
		
		$l = 0;                            				// 搜索的下边界
		$u = $this->totalip;            				// 搜索的上边界
		$findip = $this->lastip;        				// 如果没有找到就返回最后一条IP记录(QQWry.Dat的版本信息)
		while ($l fp, $this->firstip + $i * 7);
			$beginip = strrev(fread($this->fp, 4));        // 获取中间记录的开始IP地址
			
			if ($ip fp, $this->getlong3());
				$endip = strrev(fread($this->fp, 4));	// 获取中间记录的结束IP地址
				if ($ip > $endip)			// 用户的IP大于中间记录的结束IP地址时
				{
					$l = $i + 1;			// 将搜索的下边界修改为中间记录加一
				}
				else					// 用户的IP在中间记录的IP范围内时
				{
					$findip = $this->firstip + $i * 7;
					break;				// 则表示找到结果,退出循环
				}
			}
		}
		
		/* 获取查找到的IP地理位置信息 */
		fseek($this->fp, $findip);
		$location['beginip'] = long2ip($this->getlong());	// 用户IP所在范围的开始地址
		$offset = $this->getlong3();
		fseek($this->fp, $offset);
		$location['endip'] = long2ip($this->getlong());	// 用户IP所在范围的结束地址
		$byte = fread($this->fp, 1);				// 标志字节
		switch (ord($byte)) 
		{
			case 1: 					// 标志字节为1,表示国家和区域信息都被同时重定向
				$countryOffset = $this->getlong3();	// 重定向地址
				fseek($this->fp, $countryOffset);
				$byte = fread($this->fp, 1);		// 标志字节
				switch (ord($byte)) 
				{
					case 2:				// 标志字节为2,表示国家信息又被重定向
						fseek($this->fp, $this->getlong3());
						$location['country'] = $this->getstring();
						fseek($this->fp, $countryOffset + 4);
						$location['area'] = $this->getarea();
						break;
					default:			// 否则,表示国家信息没有被重定向
						$location['country'] = $this->getstring($byte);
						$location['area'] = $this->getarea();
						break;
				}
				break;
			case 2: 					// 标志字节为2,表示国家信息被重定向
				fseek($this->fp, $this->getlong3());
				$location['country'] = $this->getstring();
				fseek($this->fp, $offset + 8);
				$location['area'] = $this->getarea();
				break;
			default:					// 否则,表示国家信息没有被重定向
				$location['country'] = $this->getstring($byte);
				$location['area'] = $this->getarea();
				break;
		}
		
		if ($location['country'] == " CZ88.NET")		// CZ88.NET表示没有有效信息
		{
			$location['country'] = "未知";
		}
		if ($location['area'] == " CZ88.NET") 
		{
			$location['area'] = "";
		}
		return $location;
	}
	
	/**
	 * 获取客户端IP地址
	 * */
	function clientIp(){
		if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
			$onlineip = getenv('HTTP_CLIENT_IP');
		} elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
			$onlineip = getenv('HTTP_X_FORWARDED_FOR');
		} elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
			$onlineip = getenv('REMOTE_ADDR');
		} elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
			$onlineip = $_SERVER['REMOTE_ADDR'];
		}
		preg_match("/[\d\.]{7,15}/", $onlineip, $onlineipmatches);
		$onlineip = $onlineipmatches[0] ? $onlineipmatches[0] : 'unknown';
		unset($onlineipmatches);
		return $onlineip;
	}
    
	/**
	 * 构造函数,打开 QQWry.Dat 文件并初始化类中的信息
	 * @param string $filename
	 * @return IpLocation
	 */
	function IpLocation($filename = "") 
	{
		if(!$filename) $filename = dirname(__FILE__) . '/QQWry.Dat';
		if(!file_exists($filename)) exit('qqwry.dat is not exists!');
		if (($this->fp = @fopen($filename, 'rb')) !== false) 
		{
			$this->firstip = $this->getlong();
			$this->lastip = $this->getlong();
			$this->totalip = ($this->lastip - $this->firstip) / 7;
			register_shutdown_function(array(&$this, '_IpLocation'));
		}
	}
    
	/**
	* 析构函数,用于在页面执行结束后自动关闭打开的文件。
	*/
	function _IpLocation() 
	{
		fclose($this->fp);
	}
}

Copy after login
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

What are the differences between Huawei GT3 Pro and GT4? What are the differences between Huawei GT3 Pro and GT4? Dec 29, 2023 pm 02:27 PM

Many users will choose the Huawei brand when choosing smart watches. Among them, Huawei GT3pro and GT4 are very popular choices. Many users are curious about the difference between Huawei GT3pro and GT4. Let’s introduce the two to you. . What are the differences between Huawei GT3pro and GT4? 1. Appearance GT4: 46mm and 41mm, the material is glass mirror + stainless steel body + high-resolution fiber back shell. GT3pro: 46.6mm and 42.9mm, the material is sapphire glass + titanium body/ceramic body + ceramic back shell 2. Healthy GT4: Using the latest Huawei Truseen5.5+ algorithm, the results will be more accurate. GT3pro: Added ECG electrocardiogram and blood vessel and safety

Detailed explanation of the usage of return in C language Detailed explanation of the usage of return in C language Oct 07, 2023 am 10:58 AM

The usage of return in C language is: 1. For functions whose return value type is void, you can use the return statement to end the execution of the function early; 2. For functions whose return value type is not void, the function of the return statement is to end the execution of the function. The result is returned to the caller; 3. End the execution of the function early. Inside the function, we can use the return statement to end the execution of the function early, even if the function does not return a value.

What is the execution order of return and finally statements in Java? What is the execution order of return and finally statements in Java? Apr 25, 2023 pm 07:55 PM

Source code: publicclassReturnFinallyDemo{publicstaticvoidmain(String[]args){System.out.println(case1());}publicstaticintcase1(){intx;try{x=1;returnx;}finally{x=3;}}}#Output The output of the above code can simply conclude: return is executed before finally. Let's take a look at what happens at the bytecode level. The following intercepts part of the bytecode of the case1 method, and compares the source code to annotate the meaning of each instruction in

Fix: Snipping tool not working in Windows 11 Fix: Snipping tool not working in Windows 11 Aug 24, 2023 am 09:48 AM

Why Snipping Tool Not Working on Windows 11 Understanding the root cause of the problem can help find the right solution. Here are the top reasons why the Snipping Tool might not be working properly: Focus Assistant is On: This prevents the Snipping Tool from opening. Corrupted application: If the snipping tool crashes on launch, it might be corrupted. Outdated graphics drivers: Incompatible drivers may interfere with the snipping tool. Interference from other applications: Other running applications may conflict with the Snipping Tool. Certificate has expired: An error during the upgrade process may cause this issu simple solution. These are suitable for most users and do not require any special technical knowledge. 1. Update Windows and Microsoft Store apps

Analysis of location configuration examples in Nginx server Analysis of location configuration examples in Nginx server May 24, 2023 pm 02:05 PM

First, let me briefly introduce the types of location and matching rules, using the example of nginxwiki as an example: location=/{#matchesthequery/only.[configurationa]}location/{#matchesanyquery,sinceallqueriesbeginwith/,butregular#expressionsandanylongerconventionalblockswillbe#matchedfirst.[ configurationb]}location^~/im

How to intercept uri in nginx location How to intercept uri in nginx location May 18, 2023 pm 12:07 PM

Note: The root and aliasroot instructions in location only set the search root to the directory set by root, that is, the uri will not be truncated. Instead, the original uri will be used to jump to the directory to find the file. The aias instruction will truncate the matching uri, and then Use the path set by alias plus the remaining uri as a sub-path to find the uri of proxy_pass in location. If the url of proxy_pass does not have uri, if the tail is "/", the matching uri will be truncated. If the tail is not "/", then Will not truncate the matching uri if the proxy_pass url contains uri

How to Fix Can't Connect to App Store Error on iPhone How to Fix Can't Connect to App Store Error on iPhone Jul 29, 2023 am 08:22 AM

Part 1: Initial Troubleshooting Steps Checking Apple’s System Status: Before delving into complex solutions, let’s start with the basics. The problem may not lie with your device; Apple's servers may be down. Visit Apple's System Status page to see if the AppStore is working properly. If there's a problem, all you can do is wait for Apple to fix it. Check your internet connection: Make sure you have a stable internet connection as the "Unable to connect to AppStore" issue can sometimes be attributed to a poor connection. Try switching between Wi-Fi and mobile data or resetting network settings (General > Reset > Reset Network Settings > Settings). Update your iOS version:

php提交表单通过后,弹出的对话框怎样在当前页弹出,该如何解决 php提交表单通过后,弹出的对话框怎样在当前页弹出,该如何解决 Jun 13, 2016 am 10:23 AM

php提交表单通过后,弹出的对话框怎样在当前页弹出php提交表单通过后,弹出的对话框怎样在当前页弹出而不是在空白页弹出?想实现这样的效果:而不是空白页弹出:------解决方案--------------------如果你的验证用PHP在后端,那么就用Ajax;仅供参考:HTML code

See all articles