Home > Article > Backend Development > php将IP地址转换为真实地址的方法
下面将分享一个利用PHP将获取到的IP地址转换为真实实际地址的方法。代码函数摘自大名鼎鼎的康盛的Discuz源码,可以根据实际需要返回简短地址和详细地址两种形式。
<p>function convertip($ip,$integrity='simple'){</p> $return='';<br /> $integrity=in_array($integrity,array('simple','full'))?$integrity:'simple';<br /> if(preg_match("/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/",$ip)){<br /> $iparray=explode('.',$ip);<br /> if($iparray[0]==10||$iparray[0]==127||($iparray[0]==192&&$iparray[1]==168)||($iparray[0]==172&&($iparray[1]>=16&&$iparray[1]<=31))){<br /> $return='- LAN';<br /> }elseif($iparray[0]>255||$iparray[1]>255||$iparray[2]>255||$iparray[3]>255){<br /> $return='- Invalid IP Address';<br /> }else{<br /> $tinyipfile=WEB_ROOT.'./tinyipdata.dat';//IP==地址数据包精简版<br /> $fullipfile=WEB_ROOT.'./wry.dat';//IP==地址数据包完整版<br /> if($integrity=='simple'&&@file_exists($tinyipfile)){<br /> $return=convertip_tiny($ip,$tinyipfile);<br /> }elseif(@file_exists($fullipfile)){<br /> $return=convertip_full($ip,$fullipfile);<br /> }<br /> }<br /> }<br /> return $return;<br />}<br />function convertip_tiny($ip,$ipdatafile){<br /> static $fp=NULL,$offset=array(),$index=NULL;<br /> $ipdot=explode('.',$ip);<br /> $ip=pack('N',ip2long($ip));<br /> $ipdot[0]=(int)$ipdot[0];<br /> $ipdot[1]=(int)$ipdot[1];<br /> if($fp===NULL&&$fp=@fopen($ipdatafile,'rb')){<br /> $offset=@unpack('Nlen',@fread($fp,4));<br /> $index=@fread($fp,$offset['len']-4);<br /> }elseif($fp==FALSE){<br /> return '- Invalid IP data file';<br /> }<br /> $length=$offset['len']-1028;<br /> $start =@unpack('Vlen',$index[$ipdot[0]*4].$index[$ipdot[0]*4+1].$index[$ipdot[0]*4+2].$index[$ipdot[0]*4+3]);<br /> for ($start=$start['len']*8+1024;$start<$length;$start+=8){<br /> if ($index{$start}.$index{$start+1}.$index{$start+2}.$index{$start+3}>=$ip){<br /> $index_offset=@unpack('Vlen',$index{$start+4}.$index{$start+5}.$index{$start+6}."\x0");<br /> $index_length=@unpack('Clen',$index{$start+7});<br /> break;<br /> }<br /> }<br /> @fseek($fp,$offset['len']+$index_offset['len']-1024);<br /> if($index_length['len']){<br /> return '- '.@fread($fp,$index_length['len']);<br /> }else{<br /> return '- Unknown';<br /> }<br />}<br />function convertip_full($ip,$ipdatafile){<br /> if(!$fd=@fopen($ipdatafile,'rb')){<br /> return '- Invalid IP data file';<br /> }<br /> $ip=explode('.',$ip);<br /> $ipNum=$ip[0]*16777216+$ip[1]*65536+$ip[2]*256+$ip[3];<br /> if(!($DataBegin=fread($fd,4))||!($DataEnd=fread($fd,4))) return;<br /> @$ipbegin=implode('',unpack('L',$DataBegin));<br /> if($ipbegin<0) $ipbegin+=pow(2,32);<br /> @$ipend=implode('',unpack('L',$DataEnd));<br /> if($ipend<0) $ipend+=pow(2,32);<br /> $ipAllNum=($ipend-$ipbegin)/7+1;<br /> $BeginNum=$ip2num=$ip1num=0;<br /> $ipAddr1=$ipAddr2='';<br /> $EndNum=$ipAllNum;<br /> while($ip1num>$ipNum||$ip2num<$ipNum){<br /> $Middle= intval(($EndNum+$BeginNum)/2);<br /> fseek($fd,$ipbegin+7*$Middle);<br /> $ipData1=fread($fd,4);<br /> if(strlen($ipData1)<4){<br /> fclose($fd);<br /> return '- System Error';<br /> }<br /> $ip1num=implode('',unpack('L',$ipData1));<br /> if($ip1num<0) $ip1num+=pow(2,32);<br /> if($ip1num>$ipNum){<br /> $EndNum=$Middle;<br /> continue;<br /> }<br /> $DataSeek=fread($fd,3);<br /> if(strlen($DataSeek)<3){<br /> fclose($fd);<br /> return '- System Error';<br /> }<br /> $DataSeek=implode('',unpack('L',$DataSeek.chr(0)));<br /> fseek($fd,$DataSeek);<br /> $ipData2=fread($fd,4);<br /> if(strlen($ipData2)<4){<br /> fclose($fd);<br /> return '- System Error';<br /> }<br /> $ip2num=implode('',unpack('L',$ipData2));<br /> if($ip2num<0) $ip2num+=pow(2,32);<br /> if($ip2num<$ipNum){<br /> if($Middle==$BeginNum){<br /> fclose($fd);<br /> return '- Unknown';<br /> }<br /> $BeginNum=$Middle;<br /> }<br /> }<br /> $ipFlag=fread($fd,1);<br /> if($ipFlag==chr(1)){<br /> $ipSeek=fread($fd,3);<br /> if(strlen($ipSeek)<3){<br /> fclose($fd);<br /> return '- System Error';<br /> }<br /> $ipSeek=implode('',unpack('L',$ipSeek.chr(0)));<br /> fseek($fd,$ipSeek);<br /> $ipFlag=fread($fd,1);<br /> }<br /> if($ipFlag==chr(2)){<br /> $AddrSeek=fread($fd,3);<br /> if(strlen($AddrSeek)<3){<br /> fclose($fd);<br /> return '- System Error';<br /> }<br /> $ipFlag=fread($fd,1);<br /> if($ipFlag==chr(2)){<br /> $AddrSeek2=fread($fd,3);<br /> if(strlen($AddrSeek2)<3){<br /> fclose($fd);<br /> return '- System Error';<br /> }<br /> $AddrSeek2=implode('',unpack('L',$AddrSeek2.chr(0)));<br /> fseek($fd,$AddrSeek2);<br /> }else{<br /> fseek($fd,-1,SEEK_CUR);<br /> }<br /> while(($char=fread($fd,1)) != chr(0))<br /> $ipAddr2 .= $char;<br /> $AddrSeek=implode('',unpack('L',$AddrSeek.chr(0)));<br /> fseek($fd,$AddrSeek);<br /> while(($char=fread($fd,1)) != chr(0))<br /> $ipAddr1 .= $char;<br /> }else{<br /> fseek($fd,-1,SEEK_CUR);<br /> while(($char=fread($fd,1)) != chr(0))<br /> $ipAddr1 .= $char;<br /> $ipFlag=fread($fd,1);<br /> if($ipFlag==chr(2)){<br /> $AddrSeek2=fread($fd,3);<br /> if(strlen($AddrSeek2)<3){<br /> fclose($fd);<br /> return '- System Error';<br /> }<br /> $AddrSeek2=implode('',unpack('L',$AddrSeek2.chr(0)));<br /> fseek($fd,$AddrSeek2);<br /> }else{<br /> fseek($fd,-1,SEEK_CUR);<br /> }<br /> while(($char=fread($fd,1)) != chr(0))<br /> $ipAddr2 .= $char;<br /> }<br /> fclose($fd);<br /> if(preg_match('/http/i',$ipAddr2)){<br /> $ipAddr2='';<br /> }<br /> $ipaddr="$ipAddr1 $ipAddr2";<br /> $ipaddr=preg_replace('/CZ88\.NET/is','',$ipaddr);<br /> $ipaddr=preg_replace('/^\s*/is','',$ipaddr);<br /> $ipaddr=preg_replace('/\s*$/is','',$ipaddr);<br /> if(preg_match('/http/i',$ipaddr)||$ipaddr==''){<br /> $ipaddr='- Unknown';<br /> }<br /> return '- '.$ipaddr;<br /><p>}
以上代码使用方法示例如下:
<p>define('WEB_ROOT',dirname(__FILE__));</p><p>echo convertip('112.65.242.67','full');
注意:
wry.dat请到www.cz88.net下载!