PHP判断IP并转跳到相应城市分站

字体大小: 中小 标准 ->行高大小: 标准

今天研究了个根据IP显示天气的帖子(PHPCHINA原创区),感觉很好,正好又在落伍上见到一个“财迷”在卖他做的根据IP转跳城市分站的程序,鄙视之余就修改了一下根据IP显示天气的代码,效果还不错,只有两个页面和一个DAT格式(纯真)的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("(我们一定要解放台湾!!!)", "", $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的强大功能吧?

至于如何获取客户端IP不用细谈大家心中自然清楚,但是为了照顾一下和我一样的菜鸟,还是把显示页面的代码顺便贴出来吧:
<?php  
 
header('Content-Type: text/html; charset=utf-8');  
$starttime = getmicrotime(); //获得页面开始执行时间  
define('WROOT', dirname(__FILE__)); //定义程序目录  
 
    function GetIP() { //获取IP  
        if ($_SERVER["HTTP_X_FORWARDED_FOR"])  
        $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];  
        else if ($_SERVER["HTTP_CLIENT_IP"])  
        $ip = $_SERVER["HTTP_CLIENT_IP"];  
        else if ($_SERVER["REMOTE_ADDR"])  
        $ip = $_SERVER["REMOTE_ADDR"];  
        else if (getenv("HTTP_X_FORWARDED_FOR"))  
        $ip = getenv("HTTP_X_FORWARDED_FOR");  
        else if (getenv("HTTP_CLIENT_IP"))  
        $ip = getenv("HTTP_CLIENT_IP");  
        else if (getenv("REMOTE_ADDR"))  
        $ip = getenv("REMOTE_ADDR");  
        else 
        $ip = "Unknown";  
        return $ip;  
    }  
 
 
        define('__QQWRY__', WROOT."/QQWry.Dat");  //QQ的ip库  
        include_once WROOT.'/QQWry.class.php';  
        $QQWry=new QQWry;  
        $QQWry->QQWry(GetIP());  
        $country = iconv('GB2312','UTF-8',$QQWry->Country);//注意编码,QQWry.DAT读出来的地址默认为GB2312  
 
/* 
 * 页面转跳部分 
 */ 
        if(strstr($country,"郑州")!=NULL){  
        echo "zhengzhou.abc.com";//...向相应城市页面转跳,本例只是打印网址,转跳代码省略  
        }  
        //else if ....更多城市的判断,代码省略  
        else{  
        echo $country.iconv('GB2312','UTF-8',$QQWry->Local)."<br/>";  
        //没有匹配分站的则。。。省略  
        }  
          
 
 
 
/* 
 * 获得页面当前时间 
 */ 
function getmicrotime(){  
    list($msec, $sec) = explode(" ", microtime());  
    return (float)$sec+(float)$msec;  
}  
/* 
 * 获得页面执行时间 
 */ 
function getruntime($starttime){  
    return getmicrotime()-$starttime;  
}  
 
printf('页面执行时间:%.4f秒',getruntime($starttime));  
?> 

可以了,至于QQWry.DAT文件,建议你去纯真IP的网站上去现在最新版的。

此文章由 http://www.ositren.com 收集整理 ,地址为: http://www.ositren.com/htmls/1023.html