PHP获取本机IP与hosts文件完全无关,因为$_SERVER['SERVER_ADDR']、gethostbyname(gethostname())等直接读取网络接口,不经过DNS解析;只有gethostbyname()、curl_init()等涉及域名解析的函数才受hosts影响。

PHP获取本机IP和hosts文件完全无关
PHP里用 $_SERVER['SERVER_ADDR']、gethostbyname(gethostname()) 或 exec('hostname -I') 获取的是当前运行PHP的服务器真实网络接口IP,不经过DNS解析,也不查 /etc/hosts(Linux/macOS)或 C:\Windows\System32\drivers\etc\hosts(Windows)。改hosts只影响域名到IP的映射,对“本机”这个概念无任何作用。
哪些PHP函数会受hosts影响?只有涉及域名解析的才可能
真正走DNS解析的函数才会被hosts干扰,比如:
-
gethostbyname('localhost')→ 如果hosts把localhost指向127.0.0.2,就返回那个值 -
curl_init('http://mydev.local')→ 若mydev.local在hosts里绑定到192.168.1.100,curl就会连那个地址 -
file_get_contents('http://api.example.com')→ 同样依赖DNS,hosts可覆盖解析结果
但注意:这些都不是“获取本机IP”,而是访问外部地址时的解析环节。
常见误操作:用$_SERVER['REMOTE_ADDR']当本机IP
这是最典型的混淆点:$_SERVER['REMOTE_ADDR'] 是客户端(浏览器)的真实IP,不是PHP所在服务器的IP。它和hosts毫无关系,但容易被当成“本机IP”误用。
立即学习“PHP免费学习笔记(深入)”;
正确获取本机IP的方式取决于场景:
- Web服务监听地址 → 用
$_SERVER['SERVER_ADDR'](前提是没套反向代理) - 命令行脚本 → 推荐
gethostbyname(gethostname()),但注意某些容器环境 hostname 不解析为实际IP,此时得用exec('ip -4 route | grep default | head -1 | awk \'{print $3}\') - 多网卡环境 →
$_SERVER['SERVER_ADDR']可能是0.0.0.0,这时必须主动枚举接口,比如读取/sys/class/net/*/address或调用netifaces(需Python辅助)
hosts改错可能导致“看似本机IP异常”的假象
比如你在hosts里写了一行:127.0.0.1 myapp.local,然后PHP里写 $ip = gethostbyname('myapp.local');,得到 127.0.0.1。这不是“获取本机IP”,只是查了一个被hosts劫持的域名。如果误把这个值当作服务器对外IP用于日志、签名或API回调,就会出问题。
更隐蔽的问题是:某些框架(如Laravel)在生成URL时用 request()->getHost() + request()->getScheme() 拼接,而 getHost() 的值来自HTTP请求头(可被伪造),若再配合错误的hosts配置做本地测试,容易让开发环境URL指向内网或回环地址,上线后失效。
真正需要关注的,从来不是hosts,而是你调用的函数到底在查什么、走哪条路径、是否跨了代理或容器网络。











