$_server[‘http_host’]为空或错误是因为反向代理未透传host头或php-fpm未信任该头;应配置proxy_set_header host $host;和fastcgi_param http_host $host;,勿依赖gethostname()或$_server[‘server_name’]获取业务域名。
PHP $_SERVER['HTTP_HOST'] 为空或不正确
容器内 PHP 应用通过 Nginx/Apache 反向代理接入时,$_SERVER['HTTP_HOST'] 经常为空或返回容器内部 IP(如 172.18.0.3),根本原因是反向代理未透传 Host 头,或 PHP 运行模式(如 FPM)未信任该头字段。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- Nginx 配置中必须显式设置
proxy_set_header Host $host;(不能只写$http_host,否则可能丢失端口或协议信息) - 若使用 PHP-FPM,确认
fastcgi_param HTTP_HOST $host;已在fastcgi_params或站点配置中启用 - 检查是否启用了
use_fastcgi_ignore_client_abort类似干扰项——它不会影响 Host,但容易让人误判为“请求被截断” - 临时验证:在 PHP 中加一句
var_dump($_SERVER['HTTP_HOST'], $_SERVER['SERVER_NAME'], $_SERVER['REQUEST_URI']);,对比请求头原始值(curl -H "Host: example.com" http://localhost)
Docker 网络模式导致 gethostname() 返回容器 ID
默认 bridge 模式下,PHP 调用 gethostname() 或 php_uname('n') 得到的是类似 3a7f9b2e8c1d 的容器 ID,而非业务域名。这不是 bug,是 Linux 容器命名机制的自然表现。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 不要依赖
gethostname()获取业务域名;它只反映容器 OS 层主机名,与 DNS 或反向代理无关 - 需要域名时,应从请求上下文提取:
$_SERVER['HTTP_HOST'](经正确透传后)、或环境变量注入(如docker run -e APP_DOMAIN=example.com) - 若必须在启动时读取,可在
entrypoint.sh中写入配置文件:echo "APP_DOMAIN=${APP_DOMAIN:-localhost}" > /app/config/domain.php - 避免在 CLI 模式下调用
gethostname()并期望它等于 Web 域名——CLI 和 FPM 是两个完全独立的执行上下文
$_SERVER['SERVER_NAME'] 始终为 localhost
这个值由 Web 服务器(Nginx/Apache)自身配置决定,不是从请求头读取的。SERVER_NAME 默认取自 server_name 指令,且不会随 Host 头动态变化。Docker 内若没显式配置,Nginx 就回退到 localhost。