Reputation: 29
I've recently switched from apache to nginx. My app is located under /var/www/html and has the following structure:
# tree -a /var/www/html
/var/www/html
├── .htaccess
├── folder1
│ ├── .htaccess
│ └── index.php
├── folder2
│ ├── .htaccess
│ └── index.php
├── index.php
├── file1.php
└── file2.php
.htaccess files in all directories are the same:
# cat /var/www/html/.htaccess
AddDefaultCharset UTF-8
Options +FollowSymLinks
Options -Indexes
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(assets)/ - [L,NE]
RewriteRule ^/?$ index.php?param1=main [QSA,L]
RewriteRule ^([-a-zA-Z0-9_]+)/$ index.php?param1=$1 [QSA,L]
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ index.php?param1=$1¶m2=$2 [QSA,L]
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ index.php?param1=$1¶m2=$2¶m3=$3 [QSA,L]
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ index.php?param1=$1¶m2=$2¶m3=$3¶m4=$4 [QSA,L]
RewriteRule ^file1.xml$ file1.php [L]
RewriteRule ^file2.xml$ file2.php [L]
ErrorDocument 400 /error/400/
ErrorDocument 401 /error/401/
ErrorDocument 403 /error/403/
ErrorDocument 404 /error/404/
ErrorDocument 500 /error/500/
RedirectMatch (.*)\.inc /error/404/
RedirectMatch (.*)\.tpl /error/404/
Now I am trying to build the nginx config. My goal is to make the following rewrites:
example.com or example.com/ -> example.com/index.php?param1=main
example.com/anything or example.com/anything/ -> example.com/index.php?param1=anything
example.com/anything/else or example.com/anything/else/ -> example.com/index.php?param1=anything¶m2=else
etc...
And the same for folder1 and folder2
example.com/folder1 or example.com/folder1/ -> example.com/folder1/index.php?param1=main
example.com/folder1/anything or example.com/folder1/anything/ -> example.com/folder1/index.php?param1=anything
etc...
Nginx config currently looks like:
server {
listen 443 ssl;
server_name example.com;
charset utf-8;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
root /var/www/html;
index index.html index.htm index.php;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
I used online converter and placed rules under location / {
but that did not work. Url like example.com/anything shows 404 and example.com/anything/ tries to download file
Upvotes: 0
Views: 1635
Reputation: 49692
There is more than one way to do this. But the following example uses a named location to collect together all of the rewrite rules.
location / {
try_files $uri $uri/ @rewrite;
}
location @rewrite {
rewrite ^/$ /index.php?param1=main? last;
rewrite ^/([-a-zA-Z0-9_]+)/$ /index.php?param1=$1? last;
rewrite ^/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ /index.php?param1=$1¶m2=$2? last;
rewrite ^/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ /index.php?param1=$1¶m2=$2¶m3=$3? last;
rewrite ^/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ /index.php?param1=$1¶m2=$2¶m3=$3¶m4=$4? last;
rewrite ^/file1.xml$ /file1.php last;
rewrite ^/file2.xml$ /file2.php last;
return 404;
}
All Nginx URIs begin with a leading /
. I am assuming that the default action is to return 404 if none of the rules match. The trailing ?
prevents any original parameters being appended to the rewritten URI, if you want the original parameters appended, remove the trailing ?
. See this document for details.
Note: In your question you state that you want to accept example.com/anything/else
or example.com/anything/else/
. This is not what the existing .htaccess
does. To make the trailing /
optional, add a ?
after the final /
before the $
. For example:
rewrite ^/([-a-zA-Z0-9_]+)/?$ /index.php?param1=$1? last;
You can repeat this pattern for other folders, but it will look very messy. This logic belongs inside index.php
, but an Nginx example is given below:
location /folder1 {
try_files $uri $uri/ @rewrite1;
}
location @rewrite1 {
rewrite ^/folder1/?$ /folder1/index.php?param1=main? last;
rewrite ^/folder1/([-a-zA-Z0-9_]+)/$ /folder1/index.php?param1=$1? last;
...
}
Notice that the regular expression and the rewritten URI both need to include the folder name.
Upvotes: 1