PHP获取IP地址所在地信息的实例(使用纯真IP数据库qqwry.dat)

2018-09-07 19:17

阅读:303

  如下所示:

   <?php $data = 254.254.254.254; echo ip2long($data); function getIP() { if(getenv(HTTP_CLIENT_IP) && strcasecmp(getenv(HTTP_CLIENT_IP), unknown)) $ip = getenv(HTTP_CLIENT_IP); elseif(getenv(HTTP_X_FORWARDED_FOR) && strcasecmp(getenv(HTTP_X_FORWARDED_FOR), unknown)) $ip = getenv(HTTP_X_FORWARDED_FOR); elseif (getenv(REMOTE_ADDR) && strcasecmp(getenv(REMOTE_ADDR), unknown)) $ip = getenv(REMOTE_ADDR); elseif (isset($_SERVER[REMOTE_ADDR]) && $_SERVER[REMOTE_ADDR] && strcasecmp($_SERVER[REMOTE_ADDR], unknown)) $ip = $_SERVER[REMOTE_ADDR]; else $ip = 0.0.0.0; return $ip; } class IpLocation { //数据文件指针 var $fp; var $firstip; var $lastip; var $totalip; function getlong() { //unpack从二进制字符串对数据进行解包 //将读取的little-endian编码的4个字节转化为长整型数,fread安全读取二进制文件 $result = unpack(Vlong, fread($this->fp, 4)); return $result[long]; } function getlong3() { //将读取的little-endian编码的3个字节转化为长整型数 $result = unpack(Vlong, fread($this->fp, 3).chr(0)); return $result[long]; } function packip($ip) { //pack把数据装入一个二进制字符串 //ip2long将IP地址转成无符号的长整型,也可以用来验证IP地址 return pack(N, intval(ip2long($ip))); } function getstring($data = ) { $char = fread($this->fp, 1); while (ord($char) > 0) { //ord返回字符的ASCII值,字符串按照C格式保存,以\0结束 $data .= $char; $char = fread($this->fp, 1); } return $data; } 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; } function getlocation($ip) { if (!$this->fp) return null; // 如果数据文件没有被正确打开,则直接返回空 $location[ip] = gethostbyname($ip); // 域名转化为IP地址 $ip = $this->packip($location[ip]); // 将输入的IP地址转化为可比较的IP地址 // 不合法的IP地址会被转化为255 // 对分搜索 $l = 0; // 搜索的下边界 $u = $this->totalip; // 搜索的上边界 $findip = $this->lastip; // 如果没有找到就返回最后一条IP记录(QQWry.Dat的版本信息) while ($l <= $u) { // 当上边界小于下边界时,查找失败 $i = floor(($l + $u) / 2); // 计算近似中间记录 fseek($this->fp, $this->firstip + $i * 7); $beginip = strrev(fread($this->fp, 4)); // 获取中间记录的开始IP地址,strrev反转字符串 // strrev函数在这里的作用是将little-endian的压缩IP地址转化为big-endian的格式,便于比较 //关于little-endian与big-endian 参考:用户的IP小于中间记录的开始IP地址时 $u = $i - 1; // 将搜索的上边界修改为中间记录减一 } else { fseek($this->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; // 则表示找到结果,退出循环 } } } 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] == CZNET) { // CZNET表示没有有效信息 $location[country] = 未知; } if ($location[area] == CZNET) { $location[area] = ; } return $location; } /** * 构造函数,打开 QQWry.Dat 文件并初始化类中的信息 */ function IpLocation($filename = qqwry.dat) { $this->fp = 0; 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() { if ($this->fp) { fclose($this->fp); } $this->fp = 0; } } header(content-Type: text/html; charset=gbk); $ipOrDomain=110.0.0.0; //$ipOrDomain=

  以上这篇PHP获取IP地址所在地信息的实例(使用纯真IP数据库qqwry.dat)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。


评论


亲,登录后才可以留言!