NGINX相对路径配置问题:PHP应用子目录访问异常排查
问题根源
你的NGINX配置没有为/acme路径单独设置上下文,导致所有相对路径请求都会基于服务器根目录/var/www解析,而非应用所在的/var/www/acme子目录。
具体来说:
- 当访问
http://acme.com:8080/acme时,NGINX的root /var/www会把请求映射到/var/www/acme,但页面里的相对路径login会被浏览器解析为http://acme.com:8080/login,而非http://acme.com:8080/acme/login。 - 重写规则(Rule3)会把
/login重写为/login.php,结合root /var/www,最终就会加载/var/www/login.php,而非预期的/var/www/acme/login.php。
修复方案
为/acme单独配置location块,将该路径的根目录指向应用所在目录,并调整重写和PHP处理规则:
修改后的核心配置如下:
server { listen 8080; server_name acme.com www.acme.com; root /var/www; index index.html index.php index.htm; # 处理/acme路径的请求 location /acme { alias /var/www/acme; index index.php; # 存在的目录重写为目录下的index.php if (-d $request_filename) { rewrite ^(.+)$ $1/index.php last; } # 存在的非PHP文件直接返回 if (-f $request_filename) { set $rule_0 1$rule_0; } if ($request_filename !~* \.php$) { set $rule_0 2$rule_0; } if ($rule_0 = "21") { break; } # 文件/目录不存在时追加.php后缀 if (!-e $request_filename) { rewrite ^/acme/(.+)$ /acme/$1.php last; } # 处理PHP文件请求 location ~ \.php$ { fastcgi_param SCRIPT_FILENAME $request_filename; include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php7.4-fpm.sock; include fastcgi_params; } } # 限制根路径访问,符合安全需求 location / { deny all; return 403; } location ~ /\.ht { deny all; } }
关键调整说明
location /acme+alias:用alias确保/acme路径的请求映射到/var/www/acme,服务器根目录仍保留为/var/www。- 重写规则适配:Rule3的重写路径改为
^/acme/(.+)$ /acme/$1.php,确保追加.php后缀时仍在/acme路径下。 - PHP路径参数:使用
$request_filename替代$document_root$fastcgi_script_name,因为alias会自动处理路径映射,$request_filename已经是正确的文件路径(如/var/www/acme/login.php)。 - 根路径限制:新增
location /的deny all规则,禁止直接访问根路径,满足安全要求。
额外优化建议
可以用try_files替代部分if规则,更符合NGINX推荐用法:
location /acme { alias /var/www/acme; index index.php; try_files $uri $uri/ $uri.php /acme/index.php; location ~ \.php$ { fastcgi_param SCRIPT_FILENAME $request_filename; include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php7.4-fpm.sock; include fastcgi_params; } }
try_files可简洁实现文件存在检查、目录跳转和.php后缀追加逻辑。
内容的提问来源于stack exchange,提问作者Volomike
相关产品推荐
相关产品推荐

