目前项目的要求是:只需要城市,不需要省(因为城市不会冲突)、区、具体地址。
在网上找了相关的ip库,大多都是省市区什么都连在一起的。
请问大家有没有相关接口,或者最新的ip库。

解决方案 »

  1.   

    我前几天刚好做了个类似的。ip库用纯真的ip库就可以了,你可以在网上下载到,这个ip库基本上每周都更新。
    下面是已经已经写好的类,你可以直接用,其中$Local 就是你需要的城市的名字
    class Ip2Location
    {        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 = $this->IpToInt ( $dotip );            $this->fp= @fopen($C->INCPATH.'QQWry.Dat', "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 ( ) ;
                    
                }else {
                    $nRet = 3 ;
                    $this->Country = '未知' ;
                    $this->Local = '' ;
                }
                @fclose ( $this->fp ) ;
                return $nRet ;
            }        function IpToInt($Ip) {
                $array=@explode('.',$Ip);
                $Int=($array[0] * 256*256*256) + ($array[1]*256*256) + ($array[2]*256) + $array[3];
                return $Int;
            }}
    ?>一个演示,获得ip获得城市名字,然后通过google api查找到经纬度坐标并显示在地图上:
    http://t.39job.net/lookat
      

  2.   

    补充:纯真ip数据库可以在这里下载:http://www.crsky.com/soft/2611.html