Php 如何知道客户端在连接到我的服务器时使用的是哪个版本的Internet协议(IP)?

Php 如何知道客户端在连接到我的服务器时使用的是哪个版本的Internet协议(IP)?,php,Php,我想通过php检查是否有人通过IPv4或IPv6连接到我的站点 客户端地址可以在$\u服务器[“REMOTE\u ADDR”]中找到,但是如何检查它是IPv4还是IPv6?如何计算服务器[“REMOTE\u ADDR”]中的和/或“:”的数量呢 如果有超过0的': >,并且在 $yServer [“ReaveTyAdDR”] < /代码>中没有“ > >,我想您可以考虑用户通过IPv6连接。 另一种解决方案可能是使用:有(请参阅本页末尾)似乎与IPv4和IPv6相关: FILTER\u FL

我想通过php检查是否有人通过IPv4或IPv6连接到我的站点


客户端地址可以在
$\u服务器[“REMOTE\u ADDR”]
中找到,但是如何检查它是IPv4还是IPv6?

如何计算
服务器[“REMOTE\u ADDR”]中的
和/或“
”的数量呢

如果有超过0的'<代码>:<代码> >,并且在<代码> $yServer [“ReaveTyAdDR”] < /代码>中没有“<代码> > <代码> >,我想您可以考虑用户通过IPv6连接。


另一种解决方案可能是使用:有(请参阅本页末尾)似乎与IPv4和IPv6相关:

FILTER\u FLAG\u IPV4
(整数)
允许 “验证ip”中只有IPv4地址 过滤器

FILTER\u FLAG\u IPV6
(整数)
允许 “验证ip”中只有IPv6地址 过滤器


IPv4地址都匹配正则表达式
/^\d{1,3}(\.\d{1,3}){3,3}$/

您可以使用:

function ipVersion($txt) {
     return strpos($txt, ":") === false ? 4 : 6;
}

由于得票最高的答案有一个相当重要的问题,我将分享我自己的答案

如果传入的地址似乎是IPv6,则返回true;如果传入的地址似乎是IPv4(或IPv4映射的IPv6),则返回false。实际地址未进一步验证;如果需要验证,请使用
filter\u var()

function is_ipv6($address) {
    $ipv4_mapped_ipv6 = strpos($address, "::ffff:");
    return (strpos($address, ":") !== FALSE) &&
           ($ipv4_mapped_ipv6 === FALSE || $ipv4_mapped_ipv6 != 0);
}

检查IPv4

$ip = "255.255.255.255";
if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {    
    echo "Valid IPv4";
}
else {
    echo "Invalid IPv4";
}
检查IPv6

$ip = "FE80:0000:0000:0000:0202:B3FF:FE1E:8329";    
if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
    echo "Valid IPv6";
}
else {
    echo "Invalid IPv6";
}

有关更多信息,请检查PHP函数和。

您可以使用
inet\u pton

<?php

$packedIp = @inet_pton($ip);

if ($packedIp === false) {
    // invalid IP
} else if (isset($packedIp[4])) {
    // IPv6
} else {
    // IPv4
}

您可以使用
AF\u INET6
检测PHP是否使用IPv6支持编译:

<?php
if ( defined('AF_INET6') ) {
    echo 'Yes';
} else {
    echo 'No';
}
?>


看起来它能完成任务。但是嘿。。。。这是正则表达式!它可以做任何事情,只要你知道如何…不要假设有“.”它是IPv4,IPv6也可以包含IPv4样式的地址,例如:0:0:0:0:127.0.0.1在双堆栈服务器上(这是通常的部署),这将始终返回
6
,因为。要解决此问题,还需要检查字符串是否以
::ffff:
开头(您可能也想去掉它)。这有点旧,但乍一看,我会检查“.”而不是“:”。我知道,在查看$\u服务器超全局或其他东西时,这并没有太大区别,但是“:”字符可以出现在IPv4连接的其他实例中,因为它用于分隔地址和端口。无论是否指定端口,IPv6字符串OTOH都不会有点/句点。如果该字符存在,则它是IPv4。@user3137702
2001:db8::10.0.0.1
是一个完全有效的IPv6地址。错误建议!此字符串可能包含
::ffff:10.20.30.40
!它在我的服务器上运行。最好检查点
字符;它只出现在IPv4中。顺便说一下,虽然kasperd的地址有时是有效的,但服务器永远不会返回它。点确实是IPv4的证据。::ffff:10.20.30.40不是有效的IPv4,它是ipv6,尽管它是IPv4的映射。最后,本机解决方案IPv4映射地址仍然是无效的IPv4地址,为什么要将其计为IPv4?@CemKalyoncu因为从网络的角度来看,当您有一个映射的IPv4时,没有使用IPv6-因此,如果需要执行反向DNS查找或任何类似操作,则必须使用IPv4。如果要执行解析,则需要应用IPv6规则。即使发送方使用IPv4,传入通道也将是IPv6。