Nginx路径框架问题:带/index.php/路径的URL返回404且无需逐个配置目录
首先咱们来定位核心问题:你访问的URL格式是/folder3/folder4/laravel/index.php/path/somwhere,这个请求的URI不是以.php结尾,所以根本不会触发你配置里的location ~ \.php$块,而是会进入location /块执行try_files $uri $uri/ =404;——显然服务器上不存在/var/www/public/folder3/folder4/laravel/index.php/path/somwhere这个文件,自然就返回404了。
你的核心需求是无需为每个目录添加location规则,让所有/xxx/index.php/yyy格式的请求都能正确交给PHP处理,并把/yyy部分传递给框架作为路由参数,下面是针对性的解决方案:
修改后的Nginx配置
把原来的PHP处理location块替换成新规则,同时添加符号链接支持:
server { listen 8100 default_server; listen [::]:8100 default_server ipv6only=on; server_name localhost; root /var/www/public; index index.php index.html index.htm; # 允许Nginx跟随符号链接,确保你的软链接能被正确识别 symlinks on; autoindex off; location / { add_header 'Access-Control-Allow-Origin' '*'; add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept"; add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD"; if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Max-Age' 1728000; return 204; } try_files $uri $uri/ =404; } # 修改后的PHP处理规则:匹配任何包含.php的路径 location ~ ^(.+\.php)(.*)$ { # 先检查对应的PHP文件是否存在,不存在直接返回404 try_files $1 =404; fastcgi_pass php-fpm-56:9000; fastcgi_index index.php; fastcgi_buffers 16 16k; fastcgi_buffer_size 32k; # 指定实际要执行的PHP文件路径($1是捕获到的xxx/index.php部分) fastcgi_param SCRIPT_FILENAME $document_root$1; # 将index.php后面的路径部分作为PATH_INFO传递给PHP框架 fastcgi_param PATH_INFO $2; fastcgi_param PATH_TRANSLATED $document_root$1; fastcgi_read_timeout 600; include fastcgi_params; } location ~ /\.ht { deny all; } }
关键修改说明
正则匹配逻辑:
^(.+\.php)(.*)$会把请求URI拆成两部分:$1:从开头到.php的完整路径(比如/folder3/folder4/laravel/index.php)$2:.php后面的所有路由部分(比如/path/somwhere)
文件存在性校验:
try_files $1 =404;确保只有实际存在的PHP文件才会被交给php-fpm处理,避免无效请求触发错误。路由参数传递:通过
fastcgi_param PATH_INFO $2;把index.php后面的路径传递给PHP框架,这样CodeIgniter、Laravel这类框架就能正确解析路由规则了。符号链接支持:添加
symlinks on;让Nginx可以跟随你设置的指向public文件夹的软链接,确保路径解析正确。
修改后重启Nginx,再访问/folder3/folder4/laravel/index.php/path/somwhere应该就能正常响应了,而且后续新增的目录也不需要额外配置location规则。
内容的提问来源于stack exchange,提问作者James




