必须设 expose_php = off,这是最根本的一环;再在 nginx 的 php location 块中添加 fastcgi_hide_header x-powered-by,并重启 php-fpm 和重载 nginx,最后用 curl -i 直连源站验证响应头是否彻底移除。

php.ini 必须设 expose_php = Off
这是最根本的一环。Nginx 本身不生成 X-Powered-By,它只是透传 PHP-FPM 的响应头;只要 PHP 还在发,Nginx 层怎么拦都可能漏掉。所以第一步永远是关 PHP 自己的输出:
- 编辑全局
php.ini(不是.user.ini,也不是运行时用ini_set()) - 确认存在且启用该行:
expose_php = Off - 改完必须重启
php-fpm服务(systemctl restart php*-fpm),仅 reload Nginx 不生效 - 若用的是多版本 PHP(如 phpEnv 管理多个
php-fpm实例),要确认你改的是当前站点实际调用的那个版本的php.ini
Nginx 配置里加 fastcgi_hide_header X-Powered-By
即使 expose_php = Off 生效了,某些 PHP 扩展、框架中间件或自定义 header() 调用仍可能悄悄塞回 X-Powered-By。Nginx 的 fastcgi_hide_header 是最后一道过滤网,但它只对 FastCGI 响应起作用:
- 在对应站点的
server块或location ~ \.php$块内添加:fastcgi_hide_header X-Powered-By; - 不要写成
proxy_hide_header——那是给proxy_pass用的,对 PHP-FPM 无效 - 如果 phpEnv 把 PHP-FPM 接入方式配成了
proxy_pass http://127.0.0.1:9000(而非标准fastcgi_pass),那得换用proxy_hide_header X-Powered-By; - 执行
nginx -t检查语法,再nginx -s reload
别信浏览器开发者工具,用 curl -I 验证
浏览器会缓存响应头,尤其在反复刷新时容易误判。真实响应是否干净,必须靠原始 HTTP 协议层验证:
- 执行:
curl -I https://yoursite.com(注意是大写I) - 检查输出里是否彻底没有
X-Powered-By:这一行 - 如果用了 HTTPS,确保域名证书有效,否则
curl可能因 SSL 错误退出而看不到头 - 如果站点有 CDN 或 WAF(如 Cloudflare),先绕过它们直连源站测试,否则看到的是 CDN 返回的头
phpEnv 环境下容易被忽略的点
phpEnv 是多版本共存环境,配置分散、服务独立,比单版本部署更容易出错:
- 每个 PHP 版本都有自己的
php.ini和php-fpm.conf,改错版本等于白改 - phpEnv 启动的
php-fpm进程可能监听不同端口(如9001、9002),Nginx 的fastcgi_pass必须指向正确端口,否则fastcgi_hide_header不触发 - 某些 phpEnv 插件或一键脚本会自动写入
X-Powered-By到响应中,需检查~/.phpenv/versions/*/etc/php-fpm.d/*.conf里有没有php_admin_value[expose_php]覆盖项 - 如果用了 Laravel、ThinkPHP 等框架,检查中间件是否手动调用了
header('X-Powered-By: ...'),这类代码会绕过所有服务器级配置
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











