我在 PHP 中遇到了 $_SERVER['REMOTE_ADDR'] 的问题,即使服务器使用的是 IPv4,它也会提供类似 IPv6 的值。
谁能帮我解决这个问题。
然后服务器接受 IPv6 套接字上的连接。某些操作系统可以在 IPv6 套接字上同时执行 IPv4 和 IPv6。当这种情况发生时,IPv6 地址将看起来像::ffff:192.0.2.123
,或者::ffff:c000:027b
是相同的地址,但以十六进制编写。
如果您看到 IPv6 地址,2a00:8640:1::224:36ff:feef:1d89
那么您的网络服务器确实可以通过 IPv6 访问 :-)
无论如何,要将所有内容转换回规范形式,您可以使用以下内容:
// Known prefix
$v4mapped_prefix_hex = '00000000000000000000ffff';
$v4mapped_prefix_bin = pack("H*", $v4mapped_prefix_hex);
// Or more readable when using PHP >= 5.4
# $v4mapped_prefix_bin = hex2bin($v4mapped_prefix_hex);
// Parse
$addr = $_SERVER['REMOTE_ADDR'];
$addr_bin = inet_pton($addr);
if( $addr_bin === FALSE ) {
// Unparsable? How did they connect?!?
die('Invalid IP address');
}
// Check prefix
if( substr($addr_bin, 0, strlen($v4mapped_prefix_bin)) == $v4mapped_prefix_bin) {
// Strip prefix
$addr_bin = substr($addr_bin, strlen($v4mapped_prefix_bin));
}
// Convert back to printable address in canonical form
$addr = inet_ntop($addr_bin);
使用此代码,当您输入以下内容之一时:
::ffff:192.000.002.123
::ffff:192.0.2.123
0000:0000:0000:0000:0000:ffff:c000:027b
::ffff:c000:027b
::ffff:c000:27b
192.000.002.123
192.0.2.123
你总是得到规范的 IPv4 地址192.0.2.123
作为输出。
当然,IPv6 地址会作为规范的 IPv6 地址返回:2a00:8640:0001:0000:0224:36ff:feef:1d89
变为2a00:8640:1::224:36ff:feef:1d89
等。