PHP $_SERVER['REMOTE_ADDR'] 显示 IPv6

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12435582/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 03:34:07  来源:igfitidea点击:

PHP $_SERVER['REMOTE_ADDR'] shows IPv6

phpipv6

提问by Brijesh

I am facing an issue with $_SERVER['REMOTE_ADDR'] in PHP It is giving a IPv6 like value even though the server is using IPv4.

我在 PHP 中遇到了 $_SERVER['REMOTE_ADDR'] 的问题,即使服务器使用的是 IPv4,它也会提供类似 IPv6 的值。

Can anyone help me to resolve this issue.

谁能帮我解决这个问题。

回答by Sander Steffann

The server is then accepting connections on an IPv6 socket. Some operating systems can do both IPv4 and IPv6 on an IPv6 socket. When that happens the IPv6 address will look like ::ffff:192.0.2.123or ::ffff:c000:027bwhich is the same address but written in hexadecimal.

然后服务器接受 IPv6 套接字上的连接。某些操作系统可以在 IPv6 套接字上同时执行 IPv4 和 IPv6。当发生这种情况时,IPv6 地址看起来像::ffff:192.0.2.123::ffff:c000:027b是相同的地址但以十六进制写入。

If you see IPv6 addresses like 2a00:8640:1::224:36ff:feef:1d89then your webserver really isreachable over IPv6 :-)

如果你看到这样的IPv6地址2a00:8640:1::224:36ff:feef:1d89,然后你的服务器确实通过IPv6可达:-)

Anyway, to convert everything back to a canonical form you can use something like:

无论如何,要将所有内容转换回规范形式,您可以使用以下内容:

// 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);

Using this code, when you input one of the following:

使用此代码,当您输入以下内容之一时:

::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

you always get the canonical IPv4 address 192.0.2.123as output.

你总是得到规范的 IPv4 地址192.0.2.123作为输出。

And of course IPv6 addresses get returned as canonical IPv6 addresses: 2a00:8640:0001:0000:0224:36ff:feef:1d89becomes 2a00:8640:1::224:36ff:feef:1d89etc.

当然,IPv6 地址会作为规范的 IPv6 地址返回:2a00:8640:0001:0000:0224:36ff:feef:1d89变成2a00:8640:1::224:36ff:feef:1d89等。