PHP實現IP–數字互相轉換php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">html
<html xmlns="http://www.w3.org/1999/xhtml">mysql
<head>sql
<title>第一php網提供的教程--PHP實現IP--數字互相轉換</title>數據庫
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />函數
</head>ui
<body>xml
<?phphtm
/*教程
* 做者: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函數仍能獲得正確的結