最快获取本机IP的方法是直接使用$_SERVER['SERVER_ADDR'],其耗时仅约0.000002秒,比curl请求快10倍以上;其他方法如gethostbyname(gethostname())在容器中易出错,curl外网API则慢且不可靠。

直接用 $_SERVER['SERVER_ADDR'] 最快,根本不用 curl
curl 请求本机 IP 是典型“绕远路”:它要走 TCP/IP 栈、触发 DNS 解析(哪怕本地 hosts)、建立连接、等待响应——哪怕目标是 127.0.0.1,也比直接读 PHP 超全局变量慢 10 倍以上。实测在常规 FPM 环境下,$_SERVER['SERVER_ADDR'] 耗时稳定在 0.000002s 级别,而 curl_exec() 到 http://127.0.0.1/ip 平均 0.000025s 起跳,还受网络栈调度和 Web 服务器排队影响。
常见误用场景包括:想取“对外暴露的公网 IP”,就去 curl 自建接口;或混淆了“服务监听地址”和“客户端看到的入口 IP”。其实 $_SERVER['SERVER_ADDR'] 就是当前 PHP 进程绑定的 IP(如 0.0.0.0、192.168.1.100),无需任何外部依赖。
gethostbyname(gethostname()) 在容器里可能返回错的 IP
这个组合看似合理:先取主机名,再查本机解析。但它严重依赖 /etc/hosts 和 DNS 配置。Docker 容器默认把 hostname 解析到 127.0.0.1,Kubernetes Pod 的 hostname 通常不指向实际网卡 IP。实测中,gethostname() 返回 myapp-7f8d9c4b5-xvq2k,gethostbyname() 查不到就 fallback 到 127.0.0.1,完全失真。
如果你必须从主机名出发,应改用:
立即学习“PHP免费学习笔记(深入)”;
-
gethostbyaddr($_SERVER['SERVER_ADDR'])—— 反向查,更可靠 - 或直接读
/proc/net/fib_trie(Linux)配合file()解析,但仅限有权限且需精确网卡 IP 的场景
curl 请求外网 API(如 ifconfig.me)不仅慢,还不可靠
调用 curl -s https://ifconfig.me/ip 类接口,单次耗时常超 100ms,失败率高:DNS 超时、连接拒绝、SSL 握手失败、对方限流都可能导致 curl_exec() 返回空或报错 CURLOPT_TIMEOUT。更麻烦的是,它返回的是 NAT 后的公网出口 IP,不是你服务监听的 IP,语义已偏移。
如果业务真需要公网 IP(比如生成回调地址),请缓存结果并加 fallback:
- 首次启动时异步 curl 获取,写入 Redis 或本地临时文件
- 后续直接读缓存,过期时间设为 1 小时
- curl 失败时 fallback 到
$_SERVER['SERVER_ADDR']+ 端口拼接,至少保证服务可运行
真正需要性能对比时,用 microtime(true) 实测,别信文档
不同 SAPI 模式差异极大:CLI 下 $_SERVER 访问几乎零开销;而 Apache mod_php 中,部分键值是运行时懒生成的。别轻信“所有 $_SERVER 键都一样快”的说法。
实测建议写成这样:
for ($i = 0; $i < 1000; $i++) {
$t = microtime(true);
$ip = $_SERVER['SERVER_ADDR'];
$d1 += microtime(true) - $t;
$t = microtime(true);
$ch = curl_init('http://127.0.0.1');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_exec($ch);
curl_close($ch);
$d2 += microtime(true) - $t;}
注意关掉 Xdebug,禁用 opcache 预热干扰,容器环境还要排除 cgroup CPU 限频影响。真实瓶颈往往不在 PHP 层,而在 curl 底层的 socket connect 阻塞。
最易被忽略的一点:$_SERVER['SERVER_ADDR'] 在 Nginx + PHP-FPM 架构下,反映的是 FPM worker 监听的地址(如 127.0.0.1:9000),不是 Nginx 绑定的公网 IP —— 如果你要的是用户访问时看到的那个 IP,那得看 $_SERVER['HTTP_X_FORWARDED_FOR'](需 Nginx 正确配置 proxy_set_header),而不是任何 curl 方案。











