PHP$服务器[';远程地址';]显示IPv6

PHP$服务器[';远程地址';]显示IPv6,php,ipv6,Php,Ipv6,我在PHP中遇到了$\u SERVER['REMOTE\u ADDR']的问题 它给出了一个类似于IPv6的值,即使服务器正在使用IPv4 有人能帮我解决这个问题吗。服务器正在接受IPv6套接字上的连接。某些操作系统可以在IPv6套接字上同时执行IPv4和IPv6。发生这种情况时,IPv6地址将类似于::ffff:192.0.2.123或::ffff:c00:027b,这是相同的地址,但以十六进制书写 如果您看到IPv6地址,如2a00:8640:1::224:36ff:feef:1d89,那么

我在PHP中遇到了$\u SERVER['REMOTE\u ADDR']的问题 它给出了一个类似于IPv6的值,即使服务器正在使用IPv4


有人能帮我解决这个问题吗。

服务器正在接受IPv6套接字上的连接。某些操作系统可以在IPv6套接字上同时执行IPv4和IPv6。发生这种情况时,IPv6地址将类似于
::ffff:192.0.2.123
::ffff:c00:027b
,这是相同的地址,但以十六进制书写

如果您看到IPv6地址,如
2a00:8640:1::224:36ff:feef:1d89
,那么您的Web服务器确实可以通过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
等。

你确定你的服务器在IPv4上运行吗?这是因为你的web服务器绑定到[::],而不是0.0.0。谢谢。我将做一些事情来过滤IP。我尝试将您的所有示例添加到我的测试脚本中,但我从未执行前缀的条带化。对于所有示例,示例代码中的0是否过多?否,所有示例都有效。你能展示你的测试脚本吗?inet_pton(“192.000.002.123”)给出了一个警告,并在PHP5.3.6-10.qbolec上返回false:那是你平台上的一个bug。。。请转到并提交错误报告,以便进行修复。