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

35 php

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

可以找到客户端地址,$_SERVER["REMOTE_ADDR"] 如何检查它是IPv4还是IPv6?

Muk*_*ain 41

检查IPv4

$ip = "255.255.255.255";
if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {    
    echo "Valid IPv4";
}
else {
    echo "Invalid IPv4";
}
Run Code Online (Sandbox Code Playgroud)

检查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";
}
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请查看PHP函数filter_varslist of filters for validation.

  • 最后,**本地**解决方案 (3认同)

Cem*_*ncu 25

你可以用这个:

function ipVersion($txt) {
     return strpos($txt, ":") === false ? 4 : 6;
}
Run Code Online (Sandbox Code Playgroud)

  • 在双栈服务器(这是通常的部署)上,由于[IPv4映射的IPv6地址](https://en.wikipedia.org/wiki/IPv6#IPv4-mapped_IPv6_addresses),这将_always_返回"6".要解决这个问题,还要检查字符串是否以`:: ffff:`开头(你可能也想删除它). (3认同)
  • 这有点旧,但一目了然,我会检查"." 代替 ":".我知道在查看$ _SERVER超全局或其他东西时它没有太大的区别,但是":"字符可以出现在IPv4连接的其他实例中,因为它用于分隔地址和端口.无论是否指定端口,IPv6字符串OTOH都不会有点/周期.如果该字符存在,则为IPv4. (2认同)
  • @user3137702 `2001:db8::10.0.0.1` 是一个完全有效的 IPv6 地址。 (2认同)

Pas*_*TIN 6

计算'.'和/或' :' 的数量怎么样$_SERVER["REMOTE_ADDR"]

如果有超过0' :'且没有' .'符号$_SERVER["REMOTE_ADDR"],我想您可以认为您的用户是通过IPv6连接的.


另一个解决方案可能是使用过滤器扩展:有一些似乎与IPv4和IPv6相关的常量 (参见页面末尾):

FILTER_FLAG_IPV4(整数)
仅允许"validate_ip"过滤器中的IPv4地址.

FILTER_FLAG_IPV6(整数)
仅允许"validate_ip"过滤器中的IPv6地址.

  • 不要以为如果有'.' 它是IPv4,IPv6也可以包含IPv4样式的地址,例如:0:0:0:0:0:127.0.0.1 (5认同)

kel*_*nik 6

你可以使用inet_pton:

<?php

$packedIp = @inet_pton($ip);

if ($packedIp === false) {
    // invalid IP
} else if (isset($packedIp[4])) {
    // IPv6
} else {
    // IPv4
}
Run Code Online (Sandbox Code Playgroud)