1. 程式人生 > 程式設計 >PHP基於ip2long實現IP轉換整形

PHP基於ip2long實現IP轉換整形

如何將四個欄位以點分開的IP網路址協議地址轉換成整數呢?PHP裡有這麼一個函式ip2long.比如

<?php
echo ip2long("10.2.1.3");
?>

我們將得到

167903491

這是如何計算的,目前我知道有兩個演算法。其一

<?php
function ip2int($ip){
  //我們先把ip分為四段,$ip1,$ip2,$ip3,$ip4
  list($ip1,$ip4)=explode(".",$ip);
  //然後第一段乘以256的三次方,第二段乘以256的平方,第三段乘以256
  //這即是我們得到的值
  return $ip1*pow(256,3)+$ip2*pow(256,2)+$ip3*256+$ip4;
}
?>

其二,用位運算

<?php
function ip2int($ip){
  list($ip1,$ip);
  return ($ip1<<24)|($ip2<<16)|($ip3<<8)|($ip4);
}
?>

我們會發現,有些ip轉化成整數後,是負的,這是因為得到的結果是有符號整型,最大值是2147483647.要把它轉化為無符號的,可以用
sprintf("%u",ip2long($ip);

就能轉換為正整數。而且得到的結果用long2ip也可以正常轉換回原來的ip地址。也可以用ip2long來驗證一個ip是否是有效的,如

<?php
function chk_ip($ip){
  if(ip2long($ip)=="-1") {
    return false;
  }
  return true;
}
//應用
var_export(chk_ip("10.111.149.42"));
var_export(chk_ip("10.111.256.42"));
?>

將輸出true和false

把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函式仍能得到正確的結果.

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。