电话
400 9058 355
获取本机IP不能用$_SERVER['REMOTE_ADDR'],应绕开HTTP上下文;推荐用exec('ip -4 addr show eth0')解析具体网卡IPv4地址,或备选gethostbyname(gethostname())但有DNS依赖和单IP局限。
$_SERVER['REMOTE_ADDR']
很多人一上来就用 $_SERVER['REMOTE_ADDR'],结果拿到的是客户端 IP,不是本机(服务器)IP。真要查 PHP 所在机器自己的 IP 地址,得绕开 HTTP 请求上下文,直接查系统网络接口。
gethostbyname() + gethostname() 最简但有局限这是最轻量的组合,适合单网卡、主机名能正确解析的环境:
echo gethostbyname(gethostname());
但它依赖 DNS 或 /etc/hosts 配置。如果 gethostname() 返回 localhost 或解析失败,结果就是 127.0.0.1 或 false。常见于 Docker 容器、某些云主机或 /etc/hosts 被改写的情况。

exec('ip addr show') 或 ifconfig 更可靠但需权限和命令支持Linux 系统下推荐走系统命令,能精确控制网卡和地址类型:
$ip = exec("ip -4 addr show eth0 | grep -oP '(?<=inet\\s)\\d+(\\.\\d+){3}'");
注意点:
eth0 要换成你实际主网卡名(可用 ip link show 查),云服务器常用 ens3、ens5,Docker 里可能是 eth1
ip 命令比 ifconfig 更现代,但旧系统可能没装 iproute2,可 fallback 到 ifconfig eth0 | grep 'inet ' | awk '{print $2}'
disable_functions 里不能禁掉 exec、shell_exec)-4 参数,否则可能混入 IPv6 地址net_get_interfaces()(PHP 7.2+)PHP 原生函数,不用依赖外部命令,但仅限较新版本:
$interfaces = net_get_interfaces();
foreach ($interfaces as $name => $iface) {
if (isset($iface['unicast'][0]['address']) && !filter_var($iface['unicast'][0]['address'], FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
echo $iface['unicast'][0]['address'];
break;
}
}
关键逻辑:
lo(回环)、docker0、veth* 等非物理网卡FILTER_FLAG_NO_PRIV_RANGE 和 FILTER_FLAG_NO_RES_RANGE 排除私有网段(10.0.0.0/8、172.16.0.0/12、192.168.0.0/16)和保留地址,确保拿到的是公网可路由 IP(如果有的话)这个函数在 Windows 上也能用,但返回结构略有差异,建议加 isset() 判断字段存在性。
真正难的不是“怎么写一行代码”,而是判断你要的 IP 是什么:是监听服务用的绑定地址?是发 HTTP 请求时对外显示的出口 IP?还是容器内网通信用的 bridge IP?没明确场景,所有“获取本机 IP”方案都可能跑偏。
邮箱:8955556@qq.com
Q Q:8955556
本文详解如何将Go官方present工具(用于生成HTML5...
PySNMP在不同版本中对SNMP错误状态(errorSta...
time.Sleep仅阻塞当前goroutine,其他gor...
PHPfopen()创建含特殊符号的文件名失败主因是操作系统...
WooCommerce中通过代码为分组产品动态聚合子商品的属...
io.ReadFull返回io.ErrUnexpectedE...
本文详解Yii2中控制器向视图传递ActiveRecord数...
本文详解为何通过wp_set_object_terms()为...
Pytest中使用@mock.patch类装饰器会导致补丁泄...
带缓冲的channel是并发安全的FIFO队列;make(c...