本文实例讲述了php判断ip并转跳到相应城市分站的方法。分享给大家供大家参考。具体实现方法如下:
<?php
class qqwry{
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 ) ;
//echo "$cn" ;
if(ord($c[0])== 0 )
break ;
$str.= $c ;
}
//echo "$str n";
return $str ;
}
function qqwry ($dotip='') {
if( !is_string($dotip) || $dotip==''){return;}
if(preg_match("/^127/",$dotip)){$this->country="本地网络";return ;}
elseif(preg_match("/^192/",$dotip)) {$this->country="局域网";return ;}
$nret;
$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 ) ){
$nret=0 ;
$this->getcountry ( ) ;
//这样不太好..............所以..........
$this->local=str_replace("area error", "",$this->local);
}
else{
$nret=3 ;
$this->country='未知' ;
$this->local='' ;
}
fclose ( $this->fp );
$this->country=preg_replace("/(cz88.net)|(纯真网络)/","局域网/未知",$this->country);
$this->local=preg_replace("/(cz88.net)|(纯真网络)/","局域网/未知",$this->local);
//////////////看看 $nret在上面的值是什么0和3,于是将下面的行注释掉
return $nret ;
//return "$this->country $this->local";#如此直接返回位置和国家便可以了
}
function iptoint($ip) {
$array=explode('.',$ip);
$int=($array[0] * 256*256*256) + ($array[1]*256*256) + ($array[2]*256) + $array[3];
return $int;
}
}
?>
实例演示如下:
$qqwry=new qqwry;
$qqwry->qqwry("60.31.95.255");
$country = $qqwry->country;
echo $qqwry->country.",".$qqwry->local;
希望本文所述对大家的php程序设计有所帮助。
【说明】:本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:)!