phpEnv内置Nginx默认已启用ngx_http_realip_module,但需手动配置set_real_ip_from、real_ip_header等指令并重启服务,才能正确解析CDN/反向代理下的真实用户IP;同时须修改log_format使用$realip_remote_addr,并在fastcgi_param中重写REMOTE_ADDR传递至PHP。

phpEnv 是 Windows 下的绿色 PHP 集成环境,自带 Nginx(通常为 1.20+ 版本),但默认配置不处理 CDN 或反向代理场景下的真实 IP。它不会自动启用 ngx_http_realip_module 的解析逻辑,也不会预设可信代理段 —— 所以你看到的 $remote_addr 日志里全是 127.0.0.1 或 CDN 节点 IP,不是用户真实 IP。
确认 phpEnv 内置 Nginx 是否支持 realip 模块
phpEnv 编译时默认已包含 ngx_http_realip_module(无需手动加 --with-http_realip_module)。验证方法:在 phpEnv 安装目录下打开命令行,执行:
nginx -V 2>&1 | findstr realip
若输出含 --with-http_realip_module,说明模块可用;若无输出,说明当前版本未启用(极少见,多见于老旧 phpEnv 7.x 以前版本)。
常见问题:
立即学习“PHP免费学习笔记(深入)”;
- 即使模块存在,
set_real_ip_from等指令也必须显式写入配置,否则不生效 - phpEnv 的 Nginx 配置文件路径通常是
%PHPENV_HOME%\nginx\conf\nginx.conf或%PHPENV_HOME%\nginx\conf\vhost\*.conf - 修改后需点击 phpEnv 界面「重启 Nginx」或手动执行
nginx -s reload
在 phpEnv 的 Nginx 中配置 set_real_ip_from 和 real_ip_header
phpEnv 不提供 CDN 厂商 IP 段自动识别,你必须手动填入可信代理段。例如对接腾讯云 CDN,需在 http 块或具体 server 块中添加:
set_real_ip_from 101.32.0.0/16; set_real_ip_from 111.161.64.0/19; set_real_ip_from 119.29.29.29; real_ip_header X-Real-IP; real_ip_recursive on;
注意顺序:set_real_ip_from 必须出现在 real_ip_header 之前,否则 Nginx 启动会报错 invalid number of arguments in "real_ip_header" directive。
关键点:
- 不要用
set_real_ip_from 0.0.0.0/0—— 这会让任意请求都能伪造X-Real-IP,存在安全风险 - CDN 厂商头字段不同:腾讯云常用
X-Real-IP或True-Client-IP,Cloudflare 必须用Cf-Connecting-IP,阿里云默认走X-Forwarded-For最左非私有地址 -
real_ip_recursive on在多层代理(如 CDN → Nginx → PHP-FPM)时才真正有用;单层代理可关
修改 log_format 使用 $realip_remote_addr 记录真实 IP
phpEnv 默认日志格式用的是 $remote_addr,启用 realip 后它不会自动切换为真实 IP —— 必须改用 $realip_remote_addr(Nginx ≥ 1.11.0 支持,phpEnv 当前版本均满足)。
在 http 块中找到或新增:
log_format main '$realip_remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time';
access_log logs/access.log main;常见踩坑:
- 误写成
$real_ip_remote_addr(下划线错误)→ Nginx 启动失败,报unknown variable - 没重启 Nginx 或配置未加载到生效的 server 块 → 日志仍显示代理 IP
- 日志路径
logs/access.log是相对路径,实际落在 phpEnv 安装目录下的nginx\logs\access.log
phpEnv 中透传真实 IP 给 PHP 应用(无需改代码)
仅靠 Nginx 日志记录还不够,PHP 应用里 $_SERVER['REMOTE_ADDR'] 默认仍是 127.0.0.1。要让 PHP 直接读到真实 IP,需配合 fastcgi_param 传递:
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param REMOTE_ADDR $realip_remote_addr;
include fastcgi_params;
}这样 PHP 中 $_SERVER['REMOTE_ADDR'] 就等于真实客户端 IP,无需再解析 X-Forwarded-For —— 更安全、更可靠。
特别提醒:
-
fastcgi_param REMOTE_ADDR $realip_remote_addr必须放在include fastcgi_params之后,否则会被覆盖 - phpEnv 的
fastcgi_params文件里默认有fastcgi_param REMOTE_ADDR $remote_addr,这就是为什么必须重写一次 - 如果使用 Apache + php-cgi 模式(非 php-fpm),则对应用
SetEnvIf或ProxySet,但 phpEnv 默认只配了 php-fpm
真实 IP 解析依赖两件事:一是 Nginx 知道谁可信、从哪个 header 取值;二是这个值能进日志、也能进 PHP 运行时环境。缺一不可,且每一步都有明确的配置位置和校验方式 —— 漏掉任意一个 set_real_ip_from 段、写错一个变量名、或顺序颠倒,都会导致整条链路失效。



















