如何在Nginx+PHP的Docker环境中实现无.php后缀路由
解决Docker中Nginx+PHP无.php后缀URL访问问题
我明白你遇到的痛点——不带.php后缀的URL无法正确解析成PHP脚本,反而要么404要么直接下载文件。咱们来一步步解决这个问题,核心是让Nginx正确把无后缀的请求重写为.php文件,同时确保请求能交给PHP-FPM处理。
问题根源
你之前尝试的rewrite配置之所以会导致文件下载,是因为重写后的请求没有被Nginx的PHP处理location捕获到,Nginx把它当成了静态文件直接返回给浏览器了。咱们需要调整规则,让重写后的请求能顺利进入PHP-FPM的处理流程。
修改后的Nginx配置(完整版)
把你的nginx-site.conf替换成下面的内容:
server { root /var/www/html; include /etc/nginx/default.d/*.conf; index index.php index.html index.htm; client_max_body_size 30m; location / { # 先尝试访问原URI、原目录,最后交给重写规则处理无后缀PHP try_files $uri $uri/ @extensionless-php; } # 处理无后缀PHP的重写规则 location @extensionless-php { # 把无后缀的请求重写为带.php的路径,同时保留查询参数 rewrite ^(.*)$ $1.php last; } # 处理PHP脚本(包括重写过来的请求) location ~ [^/]\.php(/|$) { fastcgi_split_path_info ^(.+?\.php)(/.*)$; fastcgi_param HTTP_PROXY ""; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi.conf; # 确保重写过来的请求如果对应的.php文件不存在时返回404 try_files $uri =404; } }
关键配置解释
- location / 中的try_files:优先检查请求的URI是否是存在的文件或目录,如果都不是,就交给
@extensionless-php这个命名location处理。 - @extensionless-php:使用
rewrite ^(.*)$ $1.php last把请求路径加上.php后缀,last指令会让Nginx重新开始匹配location,这样重写后的.php路径就会被下面的PHP处理location捕获。 - PHP处理location:保留了你原来的配置,同时添加了
try_files $uri =404,避免当重写后的.php文件不存在时出现错误,直接返回404。
应用配置的步骤
- 替换本地的
nginx-site.conf为上面的内容 - 重新构建Docker镜像(因为你的Dockerfile是COPY这个配置文件到容器里的):
docker build -t my-php-nginx . - 停止并重新启动容器:
docker stop <你的容器名> docker run -d -p 80:80 --name <你的容器名> my-php-nginx
验证
现在访问myapp.com/somefile,Nginx会自动把它重写为somefile.php,并交给PHP-FPM执行,你应该能看到正常的PHP输出,而不是下载文件或者404了。
内容的提问来源于stack exchange,提问作者Gürkan Güran
相关产品推荐
相关产品推荐

