如何设置PHP环境下的Nginx配置,实现二级域名自动匹配子目录?

2026-05-07 07:281阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1038个文字,预计阅读时间需要5分钟。

如何设置PHP环境下的Nginx配置,实现二级域名自动匹配子目录?

当然可以,请您提供需要改写的原文内容,我将按照您的要求进行修改。

为什么 server_name ~^(\w+)\.example\.com$ 在 phpEnv 里常失效

phpEnv 的 Nginx 配置通常把多个站点塞进一个 server 块(比如监听 127.0.0.1:80 + server_name _),导致 server_name 正则根本没机会匹配;它只在独立 server 块中生效。实际请求进来时,Nginx 是靠 Host 请求头路由的,所以得从 $http_host 入手。

  • 直接写 server_name ~^(\w+)\.local$ → 多数情况下被主配置覆盖,压根不触发
  • $host$http_host 区别:前者是标准化后的 host(小写、无端口),后者是原始 header,更可靠
  • 正则里点号必须转义:\.,否则 . 匹配任意字符,abc123.local 也会被错捕获为 abc123l
  • phpEnv 的 root 路径通常是 /www/wwwroot/,子目录需严格对应文件系统结构,比如 /www/wwwroot/blog/

if ($http_host ~* ^([a-z0-9_-]+)\.local$) 提取子域名并设 root

这是最稳的写法,放在 server 块内、location / 外。用 set 把捕获组存成变量,再用于 rootalias

set $subdomain ""; if ($http_host ~* ^([a-z0-9_-]+)\.local$) { set $subdomain $1; } root /www/wwwroot/$subdomain;

  • 必须加 if ($subdomain = "") { return 404; },否则访问 localwww.local 会落到 /www/wwwroot//,可能暴露上层目录
  • 不推荐用 \w+:它包含大写字母和下划线,但部分 Linux 文件系统对大小写敏感,Blog.local$subdomain=Blog,而目录名是 blog/ 就 403
  • root 拼接后路径末尾不加斜杠,Nginx 会自动补;加了反而可能多出 //

PHP 脚本执行时 PATH_INFO 丢失?补 fastcgi_param

子目录下跑 ThinkPHP、Laravel 等框架时,$_SERVER['PATH_INFO'] 常为空,因为 rewrite 后没透传路径。得在 location ~ \.php$ 里显式设置:

立即学习“PHP免费学习笔记(深入)”;

location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /www/wwwroot/$subdomain$fastcgi_script_name; # 关键两行 ↓ fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param SCRIPT_NAME /index.php; include fastcgi_params; }

  • $fastcgi_path_info 是 Nginx 内置变量,只有在 location 用了正则匹配(如 ~ \.php$)才可用
  • 如果框架入口是 public/index.phproot 应设为 /www/wwwroot/$subdomain/public,否则 SCRIPT_FILENAME 会指向错位置
  • phpEnv 默认的 fastcgi_params 不含 PATH_INFO,必须手动加;漏掉就只剩 $_GET,路由全崩

调试时 curl 怎么验证子域名是否真被识别

别信浏览器地址栏——它不保证发对 Host 头。用 curl -H "Host: api.local" 直连本地 Nginx:

curl -H "Host: api.local" http://127.0.0.1 -I

  • 返回 200 但内容是 404 页面?说明 root 拼错了,检查 /www/wwwroot/api/ 是否存在且有 index.php
  • 返回 502 Bad Gateway?PHP-FPM 没监听或 fastcgi_pass 地址不对,phpEnv 默认是 127.0.0.1:9000
  • 想看变量值:临时加 return 200 "sub: $subdomain, host: $http_host\n"; 到 location 里,curl 一眼看清提取结果
  • nginx -t 只校验语法,不校验正则逻辑;error_log /var/log/nginx/error.log notice; 才能看到运行时变量值

真正卡住的地方往往不是正则写法,而是 phpEnv 的 Nginx 进程没重载配置、子目录权限不对(www 用户不可读)、或者 PATH_INFO 透传漏了一行——这些细节一漏,框架路由就静默失败,查日志都找不到线索。

本文共计1038个文字,预计阅读时间需要5分钟。

如何设置PHP环境下的Nginx配置,实现二级域名自动匹配子目录?

当然可以,请您提供需要改写的原文内容,我将按照您的要求进行修改。

为什么 server_name ~^(\w+)\.example\.com$ 在 phpEnv 里常失效

phpEnv 的 Nginx 配置通常把多个站点塞进一个 server 块(比如监听 127.0.0.1:80 + server_name _),导致 server_name 正则根本没机会匹配;它只在独立 server 块中生效。实际请求进来时,Nginx 是靠 Host 请求头路由的,所以得从 $http_host 入手。

  • 直接写 server_name ~^(\w+)\.local$ → 多数情况下被主配置覆盖,压根不触发
  • $host$http_host 区别:前者是标准化后的 host(小写、无端口),后者是原始 header,更可靠
  • 正则里点号必须转义:\.,否则 . 匹配任意字符,abc123.local 也会被错捕获为 abc123l
  • phpEnv 的 root 路径通常是 /www/wwwroot/,子目录需严格对应文件系统结构,比如 /www/wwwroot/blog/

if ($http_host ~* ^([a-z0-9_-]+)\.local$) 提取子域名并设 root

这是最稳的写法,放在 server 块内、location / 外。用 set 把捕获组存成变量,再用于 rootalias

set $subdomain ""; if ($http_host ~* ^([a-z0-9_-]+)\.local$) { set $subdomain $1; } root /www/wwwroot/$subdomain;

  • 必须加 if ($subdomain = "") { return 404; },否则访问 localwww.local 会落到 /www/wwwroot//,可能暴露上层目录
  • 不推荐用 \w+:它包含大写字母和下划线,但部分 Linux 文件系统对大小写敏感,Blog.local$subdomain=Blog,而目录名是 blog/ 就 403
  • root 拼接后路径末尾不加斜杠,Nginx 会自动补;加了反而可能多出 //

PHP 脚本执行时 PATH_INFO 丢失?补 fastcgi_param

子目录下跑 ThinkPHP、Laravel 等框架时,$_SERVER['PATH_INFO'] 常为空,因为 rewrite 后没透传路径。得在 location ~ \.php$ 里显式设置:

立即学习“PHP免费学习笔记(深入)”;

location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /www/wwwroot/$subdomain$fastcgi_script_name; # 关键两行 ↓ fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param SCRIPT_NAME /index.php; include fastcgi_params; }

  • $fastcgi_path_info 是 Nginx 内置变量,只有在 location 用了正则匹配(如 ~ \.php$)才可用
  • 如果框架入口是 public/index.phproot 应设为 /www/wwwroot/$subdomain/public,否则 SCRIPT_FILENAME 会指向错位置
  • phpEnv 默认的 fastcgi_params 不含 PATH_INFO,必须手动加;漏掉就只剩 $_GET,路由全崩

调试时 curl 怎么验证子域名是否真被识别

别信浏览器地址栏——它不保证发对 Host 头。用 curl -H "Host: api.local" 直连本地 Nginx:

curl -H "Host: api.local" http://127.0.0.1 -I

  • 返回 200 但内容是 404 页面?说明 root 拼错了,检查 /www/wwwroot/api/ 是否存在且有 index.php
  • 返回 502 Bad Gateway?PHP-FPM 没监听或 fastcgi_pass 地址不对,phpEnv 默认是 127.0.0.1:9000
  • 想看变量值:临时加 return 200 "sub: $subdomain, host: $http_host\n"; 到 location 里,curl 一眼看清提取结果
  • nginx -t 只校验语法,不校验正则逻辑;error_log /var/log/nginx/error.log notice; 才能看到运行时变量值

真正卡住的地方往往不是正则写法,而是 phpEnv 的 Nginx 进程没重载配置、子目录权限不对(www 用户不可读)、或者 PATH_INFO 透传漏了一行——这些细节一漏,框架路由就静默失败,查日志都找不到线索。