123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- <?php
- namespace Qii\Library;
- /**
- * Class ip
- *
- * @package Library
- */
- class IP
- {
- var $StartIP = 0;
- var $EndIP = 0;
- var $Country = '';
- var $Local = '';
- var $CountryFlag = 0; // 标识 Country位置
- // 0x01,随后3字节为Country偏移,没有Local
- // 0x02,随后3字节为Country偏移,接着是Local
- // 其他,Country,Local,Local有类似的压缩。可能多重引用。
- var $fp;
- var $FirstStartIp = 0;
- var $LastStartIp = 0;
- var $EndIpOff = 0;
- /**
- * 获取访问者的ip地址
- *
- * @return mixed
- */
- public function getIP()
- {
- if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
- $ip = $_SERVER['HTTP_CLIENT_IP'];
- } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
- $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
- } else {
- $ip = $_SERVER['REMOTE_ADDR'];
- }
- return $ip;
- }
- public function getStartIp($RecNo)
- {
- $offset = $this->FirstStartIp + $RecNo * 7;
- @fseek($this->fp, $offset, SEEK_SET);
- $buf = fread($this->fp, 7);
- $this->EndIpOff = ord($buf[4]) + (ord($buf[5]) * 256) + (ord($buf[6]) * 256 * 256);
- $this->StartIp = ord($buf[0]) + (ord($buf[1]) * 256) + (ord($buf[2]) * 256 * 256) + (ord($buf[3]) * 256 * 256 * 256);
- return $this->StartIp;
- }
- public function getEndIp()
- {
- @fseek($this->fp, $this->EndIpOff, SEEK_SET);
- $buf = fread($this->fp, 5);
- $this->EndIp = ord($buf[0]) + (ord($buf[1]) * 256) + (ord($buf[2]) * 256 * 256) + (ord($buf[3]) * 256 * 256 * 256);
- $this->CountryFlag = ord($buf[4]);
- return $this->EndIp;
- }
- public function getCountry()
- {
- switch ($this->CountryFlag) {
- case 1:
- case 2:
- $this->Country = $this->getFlagStr($this->EndIpOff + 4);
- $this->Local = (1 == $this->CountryFlag) ? '' : $this->getFlagStr($this->EndIpOff + 8);
- break;
- default:
- $this->Country = $this->getFlagStr($this->EndIpOff + 4);
- $this->Local = $this->getFlagStr(ftell($this->fp));
- }
- }
- public function getFlagStr($offset)
- {
- $flag = 0;
- while (1) {
- @fseek($this->fp, $offset, SEEK_SET);
- $flag = ord(fgetc($this->fp));
- if ($flag == 1 || $flag == 2) {
- $buf = fread($this->fp, 3);
- if ($flag == 2) {
- $this->CountryFlag = 2;
- $this->EndIpOff = $offset - 4;
- }
- $offset = ord($buf[0]) + (ord($buf[1]) * 256) + (ord($buf[2]) * 256 * 256);
- } else
- break;
- }
- if ($offset < 12) return '';
- @fseek($this->fp, $offset, SEEK_SET);
- return $this->getStr();
- }
- public function getStr()
- {
- $str = '';
- while (1) {
- $c = fgetc($this->fp);
- if (ord($c[0]) == 0) break;
- $str .= $c;
- }
- return $str;
- }
- public function QQwry($dotip = '')
- {
- if (!$dotip) return;
- if (preg_match("/^(127)/", $dotip)) {
- $this->Country = '本地网络';
- return $this;
- } else if (preg_match("/^(192)/", $dotip)) {
- $this->Country = '局域网';
- return $this;
- }
- $ip = $this->IpToInt($dotip);
- $this->fp = fopen(__QQWRY__, "rb");
- if ($this->fp == NULL) {
- $szLocal = "OpenFileError";
- return 1;
- }
- @fseek($this->fp, 0, SEEK_SET);
- $buf = fread($this->fp, 8);
- $this->FirstStartIp = ord($buf[0]) + (ord($buf[1]) * 256) + (ord($buf[2]) * 256 * 256) + (ord($buf[3]) * 256 * 256 * 256);
- $this->LastStartIp = ord($buf[4]) + (ord($buf[5]) * 256) + (ord($buf[6]) * 256 * 256) + (ord($buf[7]) * 256 * 256 * 256);
- $RecordCount = floor(($this->LastStartIp - $this->FirstStartIp) / 7);
- if ($RecordCount <= 1) {
- $this->Country = "FileDataError";
- fclose($this->fp);
- return 2;
- }
- $RangB = 0;
- $RangE = $RecordCount;
- // Match ...
- while ($RangB < $RangE - 1) {
- $RecNo = floor(($RangB + $RangE) / 2);
- $this->getStartIp($RecNo);
- if ($ip == $this->StartIp) {
- $RangB = $RecNo;
- break;
- }
- if ($ip > $this->StartIp) $RangB = $RecNo;
- else $RangE = $RecNo;
- }
- $this->getStartIp($RangB);
- $this->getEndIp();
- if (($this->StartIp <= $ip) && ($this->EndIp >= $ip)) {
- $this->getCountry();
- } else {
- $this->Country = '未知';
- $this->Local = '';
- }
- fclose($this->fp);
- return $this;
- }
- public function IpToInt($Ip)
- {
- $array = explode('.', $Ip, 4);
- $Int = ($array[0] * 256 * 256 * 256) + ($array[1] * 256 * 256) + ($array[2] * 256) + $array[3];
- return $Int;
- }
- /**
- * 将ip转换成整形
- *
- * @param string $ip
- * @return string
- */
- public function ip2Long($ip = null)
- {
- if (!$ip) $ip = $this->getIP();
- return sprintf("%u", ip2long($ip));
- }
- /**
- * 将长整形的数转换成ip地址
- *
- * @param $longIP
- * @return string
- */
- public function long2Ip($longIP)
- {
- if(!$longIP || intval($longIP) == 0) return 'Unknow';
- $ip1 = ($longIP >> 24) & 0xff; // 跟0xff做与运算的目的是取低8位
- $ip2 = ($longIP >> 16) & 0xff;
- $ip3 = ($longIP >> 8) & 0xff;
- $ip4 = $longIP & 0xff;
- return $ip1 . '.' . $ip2 . '.' . $ip3 . '.' . $ip4;
- }
- }
|