phpEnv的Nginx配置文件位于C:\phpEnv\nginx\conf\nginx.conf或C:\phpEnv\nginx\conf\vhost*.conf;若使用fastcgi_pass(默认模式),需在location块中配置fastcgi_param而非proxy_set_header,PHP应通过$_SERVER['HTTP_X_REAL_IP']获取真实IP。

phpEnv 是一套 Windows 下集成 PHP + Nginx + MySQL 的本地开发环境(类似 XAMPP),它默认的 Nginx 配置不透传真实客户端 IP,导致 PHP 中 $_SERVER['REMOTE_ADDR'] 恒为 127.0.0.1,日志、限流、地理判断全失效。必须手动改 Nginx 配置并确保 PHP 正确读取头字段。
phpEnv 的 Nginx 配置文件在哪?
phpEnv 的 Nginx 配置通常位于:C:\phpEnv\nginx\conf\nginx.conf 或 C:\phpEnv\nginx\conf\vhost\*.conf(取决于你是否启用了虚拟主机)。不要改错路径——改了 nginx.conf 却在 vhost 里配 proxy_pass,头照样不生效。
确认方法:打开任务管理器,找到 nginx.exe 进程 → 右键「打开文件所在位置」→ 上一级目录找 conf 文件夹。
必须加的三行 proxy_set_header
在对应 location 块(不是 http 或 server 顶层)中,proxy_pass 指令之前插入以下三行:
立即学习“PHP免费学习笔记(深入)”;
proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
注意点:
-
$proxy_add_x_forwarded_for不是$http_x_forwarded_for:前者会自动追加当前$remote_addr,后者只是原样转发客户端传来的值,易被伪造 - 如果 phpEnv 后端是 PHP-FPM(即非 proxy_pass 到其他服务,而是用
fastcgi_pass),则不用proxy_set_header,而应改fastcgi_param—— 但绝大多数 phpEnv 默认走的是fastcgi_pass 127.0.0.1:9000,不是反向代理模式 - 若你确实用
proxy_pass转发到另一个 PHP 服务(比如本地跑着两个 PHP 站点),才需要上面三行;否则重点在 FastCGI 参数
PHP 怎么拿到真实 IP?别再用 $_SERVER['REMOTE_ADDR']
phpEnv 默认没启用 realip 模块,也**不推荐**在本地开发环境开启 set_real_ip_from(因为所有请求都来自 127.0.0.1,设了反而可能误判)。直接信任 Nginx 设置的头即可:
在 PHP 代码中用:
// 优先取 X-Real-IP(单值、不易混淆)
$ip = $_SERVER['HTTP_X_REAL_IP'] ?? $_SERVER['REMOTE_ADDR'];
// 或更严谨地解析 X-Forwarded-For(取最左非私有 IP)
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ips = array_map('trim', explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']));
foreach ($ips as $ip) {
if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
continue;
}
$ip = $ip;
break;
}
}
常见错误:
- 写成
$_SERVER['X_REAL_IP'](漏了HTTP_前缀)→ 实际是$_SERVER['HTTP_X_REAL_IP'] - 没做空值判断,
$_SERVER['HTTP_X_REAL_IP']在未配置 header 时为NULL,直接 echo 会报 Notice - 本地开发时还去验证 CDN 白名单(如
set_real_ip_from 192.168.0.0/16),纯属多余,反而让$remote_addr被覆盖成127.0.0.1
真实 IP 透传的难点从来不在 Nginx 那几行配置,而在于:你得清楚自己用的是 FastCGI 还是 proxy_pass,以及 PHP 是否运行在 Nginx 同一进程(本地开发几乎总是同机),此时 X-Real-IP 就是唯一可信来源,别的都是干扰项。



















