32 位元系統下 ip2long 無法處理 IPv6 位址。本文提供兩個函式 ip2bin 與 bin2ip,支援 IPv4 與 IPv6 相互轉換為二進位字串,便於資料庫儲存與比較。
function ip2bin($ip) {
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false) {
return base_convert(ip2long($ip), 10, 2); // IPv4
}
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false) {
return false; // 非合法 IP
}
if (($ip_n = inet_pton($ip)) === false) return false;
$bits = 15; // 16 bytes = 128 bits
$ipbin = '';
while ($bits >= 0) {
$bin = sprintf("%08b", ord($ip_n[$bits]));
$ipbin = $bin . $ipbin;
$bits--;
}
return $ipbin; // 128 字元的 0/1 字串
}
function bin2ip($bin) {
if (strlen($bin) <= 32) { // IPv4
return long2ip(base_convert($bin, 2, 10));
}
if (strlen($bin) != 128) return false; // IPv6 必須 128 bits
// 補零到 128 位
$pad = 128 - strlen($bin);
for ($i = 1; $i <= $pad; $i++) $bin = "0" . $bin;
$ipv6 = '';
for ($bits = 0; $bits <= 7; $bits++) {
$bin_part = substr($bin, $bits * 16, 16);
$ipv6 .= dechex(bindec($bin_part)) . ":";
}
return inet_ntop(inet_pton(substr($ipv6, 0, -1)));
}
$ipv6 = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";
$bin = ip2bin($ipv6); // 128 位元字串
echo bin2ip($bin); // 還原為標準 IPv6 格式
CHAR(128) 或 BINARY(16) 儲存 IP,支援 IPv4/IPv6 統一查詢。ip2long 處理 IPv6 時的替代方案。提示: 64 位元系統 PHP 5.3+ 已原生支援 IPv6 的 ip2long(回傳有號整數),但為跨平台相容,採用二進位字串儲存最穩健。