从Apache(.htaccess)迁移至Nginx:URL重写规则配置求助
从Apache .htaccess迁移到Nginx的URL重写配置方案
我之前帮朋友处理过几乎一模一样的迁移需求,很清楚你现在的困惑。咱们直接上解决方案,完美匹配你原来的Apache规则效果:
核心思路
你的Apache规则是当请求的文件/目录不存在时,把请求路径作为rt参数转发到对应目录下的index.php,同时保留原查询字符串。在Nginx里我们可以用try_files配合命名location来实现,比用if指令更高效也更符合Nginx的最佳实践。
完整Nginx配置示例
server { listen 80; server_name your-domain.com; # 替换成你的实际域名 root /var/www/html; # 替换成你的网站根目录(包含test1/和test2/的上级目录) # 处理test1目录的URL重写 location /test1/ { # 先尝试访问真实文件/目录,不存在则走重写规则 try_files $uri $uri/ @test1-rewrite; } # test1的重写规则命名location location @test1-rewrite { # 捕获/test1/之后的所有路径,作为rt参数转发到index.php rewrite ^/test1/(.*)$ /test1/index.php?rt=$1 last; } # 处理test2目录的URL重写(和test1逻辑完全一致) location /test2/ { try_files $uri $uri/ @test2-rewrite; } location @test2-rewrite { rewrite ^/test2/(.*)$ /test2/index.php?rt=$1 last; } # PHP文件解析配置(必须有这个才能运行index.php) location ~ \.php$ { # 根据你的PHP版本调整套接字路径,比如php7.4就是/php7.4-fpm.sock fastcgi_pass unix:/run/php/php8.2-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
关键细节解释
try_files的作用:先检查请求的$uri是否是真实存在的文件,再检查是否是目录,如果都不存在,就跳转到后面的命名location(比如@test1-rewrite)执行重写,完全对应Apache的RewriteCond %{REQUEST_FILENAME} !-f和!-d规则。rewrite规则:^/test1/(.*)$捕获/test1/之后的所有内容(比如访问/test1/page2时,捕获到page2),然后转发到/test1/index.php?rt=$1,和Apache的RewriteRule ^(.*)$ index.php?rt=$1效果完全一致。- 保留查询字符串:Nginx的
rewrite指令默认会保留原查询字符串(对应Apache的QSA标志),比如你访问/test1/page2?id=123,重写后会自动变成/test1/index.php?rt=page2&id=123。 - PHP配置注意事项:一定要确保
fastcgi_pass的路径和你服务器上的PHP-FPM套接字路径一致,如果你用的是TCP连接(比如127.0.0.1:9000),替换成对应的地址即可。
测试验证
配置完后重启Nginx(sudo systemctl restart nginx),然后测试:
- 访问
your-domain.com/test1/:应该输出default page - 访问
your-domain.com/test1/page2:应该输出page2 - 访问
your-domain.com/test2/page2?id=456:输出page2,同时$_GET['id']能拿到456
内容的提问来源于stack exchange,提问作者Draven
相关产品推荐
相关产品推荐

