[聚合文章] PHP、MySQL,IP 轉整數存資料庫

MySQL 2017-12-17 22 阅读
MySQL

INT:0 ~ 4294967295

mysql> SELECT INET_ATON("0.0.0.0"); #0
mysql> SELECT INET_ATON("255.255.255.255"); #4294967295
mysql> SELECT INET_NTOA("0"); #0.0.0.0
mysql> SELECT INET_NTOA("4294967295"); #255.255.255.255

註:

INET_ATON = Address to number

INET_NTOA = Number to Address

PHP(32 bit)

INT:-2147483648 ~ 2147483647

var_dump(ip2long("0.0.0.0")); #int(0)
var_dump(ip2long("127.255.255.255")); #int(2147483647)
var_dump(ip2long("255.255.255.255")); #int(-1)
var_dump(ip2long("128.0.0.0")); #int(-2147483648)
var_dump(long2ip(0)); #string(7) "0.0.0.0"
var_dump(long2ip(2147483647)); #string(15) "127.255.255.255"
var_dump(long2ip(-1)); #string(15) "255.255.255.255"
var_dump(long2ip(-2147483648)); #string(9) "128.0.0.0"

因為在32位元系統,PHP int 型態有分正負號(signed),

範圍為 -2147483648 ~ 2147483647( http://php.net/manual/en/function.intval.php )

可用 sprintf(%u) 轉換成不帶正負號的 (unsigned) 的10進制字串,

可轉成:"0" ~ "4294967295"

var_dump(sprintf("%u", ip2long("0.0.0.0"))); #string(1) "0"
var_dump(sprintf("%u", ip2long("127.255.255.255"))); #string(10) "2147483647"
var_dump(sprintf("%u", ip2long("255.255.255.255"))); #string(10) "4294967295"
var_dump(sprintf("%u", ip2long("128.0.0.0"))); #string(10) "2147483648"
var_dump(long2ip(0)); #string(7) "0.0.0.0"
var_dump(long2ip(2147483647)); #string(15) "127.255.255.255"
var_dump(long2ip(4294967295)); #string(15) "255.255.255.255"
var_dump(long2ip(2147483648)); #string(9) "128.0.0.0"
PHP(64 bit)

INT:0 ~ 4294967295

var_dump(ip2long("0.0.0.0")); #int(0)
var_dump(ip2long("127.255.255.255")); #int(2147483647)
var_dump(ip2long("255.255.255.255")); #int(4294967295)
var_dump(ip2long("128.0.0.0")); #int(2147483648)
var_dump(long2ip(0)); #string(7) "0.0.0.0"
var_dump(long2ip(2147483647)); #string(15) "127.255.255.255"
var_dump(long2ip(4294967295)); #string(15) "255.255.255.255"
var_dump(long2ip(2147483648)); #string(9) "128.0.0.0"

在 64 位元的 PHP,int 最大值可到 9223372036854775807,

有無用 sprintf(%u) 不影響轉出的數字範圍

var_dump(sprintf("%u", ip2long("0.0.0.0"))); #string(1) "0"
var_dump(sprintf("%u", ip2long("127.255.255.255"))); #string(10) "2147483647"
var_dump(sprintf("%u", ip2long("255.255.255.255"))); #string(10) "4294967295"
var_dump(sprintf("%u", ip2long("128.0.0.0"))); #string(10) "2147483648"
var_dump(long2ip(0)); #string(7) "0.0.0.0"
var_dump(long2ip(2147483647)); #string(15) "127.255.255.255"
var_dump(long2ip(4294967295)); #string(15) "255.255.255.255"
var_dump(long2ip(2147483648)); #string(9) "128.0.0.0"

[其他測試]

64 位元的 PHP 將 32 位元的負數結果轉回 IP,似乎也可正常執行(環境:PHP 7.0.12)

var_dump(long2ip(-1)); #string(15) "255.255.255.255"
var_dump(long2ip(-2)); #string(15) "255.255.255.254"
var_dump(long2ip(-3)); #string(15) "255.255.255.253"
var_dump(long2ip(-2147483647)); #string(9) "128.0.0.1"
var_dump(long2ip(-2147483648)); #string(9) "128.0.0.0"

結論:

  1. IP 轉數字存進 MySQL,MySQL 欄位建議使用 INT UNSIGNED,只須 4 bytes,儲存範圍剛好 0~4294967295
  2. 可用 MySQL INET_ATON() 將IP處理成數字存入。
  3. 或先用 PHP long2ip() 處理成數字(要相容 32bit PHP,則long2ip的值須再用 sprintf(%u) 處理)

參考:

注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。