<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>第一php網提供的教程--PHP實現IP--數字互相轉換</title> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> </head> <body> <?php /* * 作者:XXXX */ //將IP轉換為數字 function ipton($ip) { $ip_arr=explode('.',$ip);//分隔ip段 foreach ($ip_arr as $value) { $iphex=dechex($value);//將每段ip轉換成16進制 if(strlen($iphex)<2)//255的16進制表示是ff,所以每段ip的16進制長度不會超過2 { $iphex='0'.$iphex;//如果轉換后的16進制數長度小於2,在其前面加一個0 //沒有長度為2,且第一位是0的16進制表示,這是為了在將數字轉換成ip時,好處理 } $ipstr.=$iphex;//將四段IP的16進制數連接起來,得到一個16進制字符串,長度為8 } return hexdec($ipstr);//將16進制字符串轉換成10進制,得到ip的數字表示 } //將數字轉換為IP,進行上面函數的逆向過程 function ntoip($n) { $iphex=dechex($n);//將10進制數字轉換成16進制 $len=strlen($iphex);//得到16進制字符串的長度 if(strlen($iphex)<8) { $iphex='0'.$iphex;//如果長度小於8,在最前面加0 $len=strlen($iphex); //重新得到16進制字符串的長度 } //這是因為ipton函數得到的16進制字符串,如果第一位為0,在轉換成數字后,是不會顯示的 //所以,如果長度小於8,肯定要把第一位的0加上去 //為什么一定是第一位的0呢,因為在ipton函數中,后面各段加的'0'都在中間,轉換成數字后,不會消失 for($i=0,$j=0;$j<$len;$i=$i+1,$j=$j+2) {//循環截取16進制字符串,每次截取2個長度 $ippart=substr($iphex,$j,2);//得到每段IP所對應的16進制數 $fipart=substr($ippart,0,1);//截取16進制數的第一位 if($fipart=='0') {//如果第一位為0,說明原數只有1位 $ippart=substr($ippart,1,1);//將0截取掉 } $ip[]=hexdec($ippart);//將每段16進制數轉換成對應的10進制數,即IP各段的值 } $ip = array_reverse($ip); return implode('.', $ip);//連接各段,返回原IP值 } echo ipton('119.255.31.226'); echo '<br>'; $num='379374783'; echo strlen($num).'<br/>'; echo ntoip($num).'<br/>'; echo 'trueipnum:'.ip2long('119.255.31.226').'<br/>'; echo 'trueip:'.long2ip('3793747831'); ?> </body> </html>
mysql自帶了inet_aton函數來實現將ip地址轉換為數字,inet_ntoa函數將數字轉換為ip。
SELECT INET_ATON( '10.122.22.1' )
上面的轉換函數為站長原創,碰巧實現了跟mysql系統函數相同的轉換效果,呵呵,興奮好久~~
原來PHP提供了ip2long和long2ip2個函數來實現IP與數字的轉換,站長做了無用功了,不過權當鍛煉邏輯思維吧~~
這是兩種實現方法,一種是在程序上實現;一種是直接在sql語句中實現,很方便,不錯,保存下來了,發到自己的博客,以后就不會忘記了。
把ip數據保存在數據庫(MySQL)中時候,我們習慣用ip2long函數生成整型,然后存放在一個int(11)類型的字段中,但是,在不同的系統平台上,ip2long函數得到的值是不同的,因此可能造成在從數據庫中讀出數據,用long2ip得到ip的時候產生錯誤,說一下我們碰到的情況:
我們用一個int(11)類型(范圍-2147483648 - 2147483647)來保存把一個ip地址用ip2long處理得到的結果,例如ip是’202.105.77.179′,那么在32位機器上得到的結果是:-899068493,而在64位機器上卻得到3395898803.然后把它寫入數據庫,由於超過int(11)的范圍,因此64位機器上的結果被保存為int(11)的最大值:2147483647.於是在從數據庫中取出的時候,便得到了錯誤的結果,會得到”127.255.255.255″這個ip地址.
解決的辦法很多,比如可以用mysql的函數:INET_ATON和INET_NTOA來處理ip地址;或者把保存ip地址的字段改為bigint類型,這樣在64位機器上雖然保存的是3395898803,使用long2ip函數仍能得到正確的結果.