2013-07-04 97 views
2

把我的問題轉化爲視角:如何將二進制轉換爲mysql中的整數?

我有一個PHP應用程序,它將用戶的IP存儲在MySQL表中。

列類型爲VARBINARY(16),應用程序使用PHP的inet_pton來形成二進制字符串。

這就是字符串有4個字節的典型IP4地址。

如何從表格中檢索這些IP,以人們可讀的形式顯示它們?

我目前的解決辦法是:

select INET_NTOA(CONV(HEX(ip),16,10)) from operation_ip; 

有沒有更直接的方式來做到這一點?

特別是CONV(HEX(x),16,10)最簡單的方法將4個字節變成一個整數(實際上我相信它甚至不是一個整數,而是一個看起來像整數的字符串)。我使用VARBINARY(16),因爲PHP的inet_pton可以返回16個字節的IPv6地址。AFAIK MySQL的INET_NTOA不支持IPv6,但目前這並不是我最關心的問題)。

+0

如果你想要一個更直接的形式,請不要將IP地址轉換爲二進制爲了將其存儲在數據庫中...或者在數據庫中同時存在地址的字符串和二進制值。 –

回答

0

MySQL有不錯的內置功能來處理這種情況:

INSERT INTO t(ip) VALUE (INET_ATON('1.2.3.4')); -- stores integer 16909060 
SELECT INET_NTOA(ip) FROM t; -- returns string '1.2.3.4' 

或者PHP的方式:

$sql = 'INSERT INTO t(ip) VALUE (' . ip2long('1.2.3.4') . '))'; 
// ip2long('1.2.3.4') = 16909060 
// reverse conversion: long2ip(16909060) returns '1.2.3.4' 
+0

如果我理解正確,您的解決方案是使用一個4字節的整數作爲列的類型。不幸的是,IPv6需要16個字節,MySQL不支持這種長整型,這就是我使用VARBINARY(16)的原因。另一方面,在某些查詢中,我100%肯定結果只包含IPv4地址的行,在這種情況下,我想快速將VARBINARY(16)轉換爲(4字節)INT。 – qbolec

+1

由於您寫下「IPv6(...)不是我最關心的問題,所以我忽略了IPv6的問題」。從v5.6.3開始,MySQL的功能正是你所需要的:['INET6_ATON()'](http://dev.mysql.com/doc/refman/5.6/en/miscellaneous-functions.html#function_inet6-aton)和['INET6_NTOA()'](http://dev.mysql.com/doc/refman/5.6/en/miscellaneous-functions.html#function_inet6-ntoa)。在此之前,你的方法可能是最好的方法。儘管如此,我並沒有將IPv4和IPv6存儲在同一列中,而是以不同的列存儲。 – RandomSeed

相關問題