首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP IP 地址轉整數:ip2long、手動位運算、MySQL INET_ATON 多方案對比

     編輯:PHP 相關知識

IPv4 地址轉無符號 32 位整數,便於資料庫範圍查詢、索引優化、位掩碼運算。本文對比 PHP 內建 ip2long、手動位運算、MySQL INET_ATON 三種方案的行為差異與最佳實踐。

方案一:PHP ip2long()(首選)

$ip = '192.168.1.101';
$long = ip2long($ip);
echo $long; // -1062731675 (有符號 32 位)

// 轉無符號顯示
printf('%u', $long); // 3232235877

// 反向轉換
echo long2ip($long); // 192.168.1.101
  • 返回 有符號整數(PHP 整數有符號),需 printf('%u') 或 sprintf('%u') 獲取無符號值;
  • long2ip() 自動處理有符號輸入;
  • 無效 IP 返回 false。

方案二:手動位運算(教學/無擴展環境)

function ip2long_manual(string $ip): int {
    $parts = explode('.', $ip);
    if (count($parts) !== 4) return 0;
    // 位移拼接
    return (($parts[0] << 24) | ($parts[1] << 16) | ($parts[2] << 8) | $parts[3]) & 0xFFFFFFFF;
}

// 使用
$long = ip2long_manual('192.168.1.101');
echo $long; // 3232235877 (已是無符號值)
  • 手動實現網絡序(大端序)拼接;
  • & 0xFFFFFFFF 確保 32 位截斷;
  • 適合理解原理、嵌入式環境無 ip2long 時。

方案三:MySQL INET_ATON / INET_NTOA(資料庫層)

-- IP 轉整數
SELECT INET_ATON('192.168.1.101'); -- 3232235877

-- 整數轉 IP
SELECT INET_NTOA(3232235877); -- 192.168.1.101

-- 範圍查詢:查找 192.168.1.0/24 內的記錄
SELECT * FROM logs
WHERE ip_int BETWEEN INET_ATON('192.168.1.0') AND INET_ATON('192.168.1.255');
  • SQL 層直接運算,無需應用層轉換;
  • INET_ATON 返回無符號整數(BIGINT),範圍查詢極快;
  • 資料庫遷移時需注意函數兼容性(PostgreSQL 用 inet 類型)。

行為差異對照表

輸入ip2long()手動位運算INET_ATON
192.168.1.101-106273167532322358773232235877
255.255.255.255-142949672954294967295
0.0.0.0000
invalidfalse0NULL

資料庫存儲最佳實踐

  1. 欄位類型:INT UNSIGNED (MySQL) / BIGINT (通用);
  2. 寫入:$ip_int = sprintf('%u', ip2long($ip)) 或 INET_ATON();
  3. 讀取:long2ip($row['ip_int']) 或 INET_NTOA();
  4. 索引:CREATE INDEX idx_ip ON logs(ip_int),範圍查詢走索引。

IPv6 處理提示

  • IPv6 128 位無法存入 32/64 位整數;
  • MySQL 5.7+ 支援 VARBINARY(16) + INET6_ATON()/INET6_NTOA();
  • PHP 用 inet_pton()/inet_ntop() 轉二進制字串存儲。

常見坑點

代碼問題修正
ip2long($_SERVER['REMOTE_ADDR'])可能返回 false(IPv6、代理頭)驗證返回值、優先用 filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)
WHERE ip = ip2long('1.2.3.4')有符號比較錯誤用 sprintf('%u', ...) 或資料庫 INET_ATON
long2ip(-1)返回 255.255.255.255 正確無問題,long2ip 內部處理

統一使用 ip2long + sprintf('%u') 或資料庫 INET_ATON,能構建高性能、可遷移的 IP 存儲查詢體系。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved