<?
define('QQWRY' , 'qqwry/'.'qqwry.dat' ) ; function IpToInt($Ip) { $array=explode('.',$Ip); $Int=($array[0] * 256*256*256) + ($array[1]*256*256) + ($array[2]*256) + $array[3]; return $Int; } function IntToIp($Int) { $b1=($Int & 0xff000000)>>24; if ($b1<0) $b1+=0x100; $b2=($Int & 0x00ff0000)>>16; if ($b2<0) $b2+=0x100; $b3=($Int & 0x0000ff00)>>8; if ($b3<0) $b3+=0x100; $b4= $Int & 0x000000ff; if ($b4<0) $b4+=0x100; $Ip=$b1.'.'.$b2.'.'.$b3.'.'.$b4; return $Ip; } class TQQwry { 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 ; 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 ; } 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 ; } function getCountry ( ) { switch ( $this->CountryFlag ) { case 1: case 2: $this->Country = $this->getFlagStr ( $this->EndIpOff+4) ; //echo sprintf('EndIpOffset=(%x)',$this->EndIpOff ); $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 )) ; } } 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(); } function getStr ( ) { $str = '' ; while ( 1 ) { $c = fgetc ( $this->fp ) ; if ( ord ( $c[0] ) == 0 ) break ; $str .= $c ; } return $str ; } function qqwry ($dotip) { $nRet; $ip = IpToInt ( $dotip );
$this->fp= @fopen(QQWRY, "r"); if ($this->fp == NULL) { $this->Country = "Open File ".QQWRY." Error"; 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 ) ){ $nRet = 0 ; $this->getCountry ( ) ; //这样不太好..............所以.......... $this->Local = str_replace("(我们一定要解放台湾!!!)", "", $this->Local);
$this->Local = str_replace("CZ88.NET", "", $this->Local);
}else { $nRet = 3 ; $this->Country = '未知' ; $this->Local = '' ; } fclose ( $this->fp ) ; return $nRet ; } } function ip2location ( $ip ) { $wry = new TQQwry ; $nRet = $wry->qqwry ( $ip ); //可以利用 $nRet做一些事情,我是让他自动记录未知IP到一个表,代码就不写了。 return $wry->Country.$wry->Local ; } ?>
define('QQWRY' , 'qqwry/'.'qqwry.dat' ) ; function IpToInt($Ip) { $array=explode('.',$Ip); $Int=($array[0] * 256*256*256) + ($array[1]*256*256) + ($array[2]*256) + $array[3]; return $Int; } function IntToIp($Int) { $b1=($Int & 0xff000000)>>24; if ($b1<0) $b1+=0x100; $b2=($Int & 0x00ff0000)>>16; if ($b2<0) $b2+=0x100; $b3=($Int & 0x0000ff00)>>8; if ($b3<0) $b3+=0x100; $b4= $Int & 0x000000ff; if ($b4<0) $b4+=0x100; $Ip=$b1.'.'.$b2.'.'.$b3.'.'.$b4; return $Ip; } class TQQwry { 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 ; 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 ; } 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 ; } function getCountry ( ) { switch ( $this->CountryFlag ) { case 1: case 2: $this->Country = $this->getFlagStr ( $this->EndIpOff+4) ; //echo sprintf('EndIpOffset=(%x)',$this->EndIpOff ); $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 )) ; } } 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(); } function getStr ( ) { $str = '' ; while ( 1 ) { $c = fgetc ( $this->fp ) ; if ( ord ( $c[0] ) == 0 ) break ; $str .= $c ; } return $str ; } function qqwry ($dotip) { $nRet; $ip = IpToInt ( $dotip );
$this->fp= @fopen(QQWRY, "r"); if ($this->fp == NULL) { $this->Country = "Open File ".QQWRY." Error"; 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 ) ){ $nRet = 0 ; $this->getCountry ( ) ; //这样不太好..............所以.......... $this->Local = str_replace("(我们一定要解放台湾!!!)", "", $this->Local);
$this->Local = str_replace("CZ88.NET", "", $this->Local);
}else { $nRet = 3 ; $this->Country = '未知' ; $this->Local = '' ; } fclose ( $this->fp ) ; return $nRet ; } } function ip2location ( $ip ) { $wry = new TQQwry ; $nRet = $wry->qqwry ( $ip ); //可以利用 $nRet做一些事情,我是让他自动记录未知IP到一个表,代码就不写了。 return $wry->Country.$wry->Local ; } ?>
解决方案 »
- 求救zend optimizer安装出错
- 求一正则
- php怎么删除目录
- 解释下@ini_set('include_path', '.;' . ROOT_PATH);
- 大家好,我遇到了URL传递中文的问题,有什么好的解决办法?
- php中自动下载文件到指定的系统目录中
- 目前最新的zend optimizer是否还不支持php5?
- 丢失$HTTP_ACCEPT_ENCODING
- 在web服务器(linux)上装个摄像头,如何实现在PHP网页中实时显示摄像?
- radio值怎么锁定不能更改包括抓包重新发送
- What's wrong of my php5+apache2 installation in windows?
- 请问各位,一组缩略图片如何让它左向右滚动?在线等...
现在我又用回以上代码了:(
附转换程序如下,数据库需要有 FILE 权限:<?
/*BY: [email protected]从 纯真网络:http://www.cz88.net 下载的IP数据,
用自带的软件解压为 qqwry.txt 后放在本目录,
然后导入 MySQL 数据库表的结构:
CREATE TABLE `qqwry2` (
`qqwryid` int(11) unsigned NOT NULL auto_increment,
`ip1` int(10) unsigned NOT NULL default '0',
`ip2` int(10) unsigned NOT NULL default '0',
`address` varchar(255) NOT NULL default '',
PRIMARY KEY (`qqwryid`)
) TYPE=MyISAM;*/$dbhost = 'localhost'; // 数据库服务器
$dbuser = 'root'; // 数据库用户名
$dbpw = ''; // 数据库密码
$dbname = 'iplocation'; // 数据库名$dbtable = 'qqwry2'; //ip数据表 1if(!mysql_connect($dbhost, $dbuser, $dbpw, $dbname, $pconnect) or !mysql_select_db($dbname)){
die("datebase error.");
}
set_time_limit(0);$fd = fopen ("qqwry.txt", "r");
$temp_filename = tempnam( "/tmp", "ip_" );
$fd2 = fopen ("$temp_filename", "w");$id = 0;while (!feof ($fd)) {
$id++;
$linestr = fgets($fd, 4096);
if(!trim($linestr)) break;
$ip1_str = trim(substr($linestr,0,15));
$ip2_str = trim(substr($linestr,16,15));
$address_str = trim(substr($linestr,32));
$ip_arr = explode(".",$ip1_str);
$ip1_str = 0;
foreach($ip_arr as $i=>$s){
$ip1_str += $s*pow(256,3-$i);
} $ip_arr = explode(".",$ip2_str);
$ip2_str = 0;
foreach($ip_arr as $i=>$s){
$ip2_str += $s*pow(256,3-$i);
}
fwrite($fd2,($id>1?"\r\n":"")."\"$id\",\"$ip1_str\",\"$ip2_str\",\"$address_str\"");
}mysql_query("TRUNCATE TABLE `$dbtable`;");
mysql_query("LOAD DATA LOCAL INFILE '".addslashes($temp_filename)."' INTO TABLE `$dbtable` FIELDS TERMINATED BY ',' ENCLOSED BY '\"' ESCAPED BY '\\\\' LINES TERMINATED BY '\\r\\n'");
fclose ($fd);
fclose ($fd2);
@unlink($temp_filename);die("导入完成.");?>
数据库大并不代表是负担,也不会消耗更多的资源。数据库的数据是线性排列的,读取定位数据是采用二分法查找,数据库现在的26w个数据,在最坏情况下,只需要大概18次的比较/跳转操作就能定位,而你说的别的数据库大概5w数据,在最坏情况下大概需要15-16次比较/跳转,不可能出现过多的负担。
当然,要是你的程序是采取直线读取/比较来判断的,则需要比较几十万次,那是程序员不懂或者不负责任造成的无必要消耗。这个和数据库无关。
==================================
直接用二分法读取数据,速度很快的。