Recently we have moved to Nginx from Apache, Under apache it used to be very easy just put some stuff on .htaccess and done.
RewriteEngine on
RewriteBase /
# only rewrite if the requested file doesn't exist
RewriteCond %{REQUEST_FILENAME} !-s
# pass the rest of the request into index.php to handle
RewriteRule ^(.*)$ /index.php/$1 [L]
The above served great to clean URL and let index.php handle all requests. but in Nginx we needed to rewrite every unique URL in location block. However this is not 'automatic' like apache.
Few examples of our rewrite location block
location / {
try_files $uri $uri/ /index.php;
}
location /p {
rewrite ^/p(?:/([a-z_]+))?$ /index.php?p=$1 last;
rewrite ^/p/all_articles/user/(.*)?$ /index.php?p=all_articles&user=$1 last;
try_files $uri $uri/ /index.php;
}
location /about_us {
rewrite ^/about_us /index.php?about_us last;
try_files $uri $uri/ /index.php;
}
location /search {
rewrite ^/search/(.*) /index.php?search=$1;
rewrite ^/search/(.*)/page/(.*)?$ /index.php?search=$1&page=$2 last;
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
the above does good job in clean URL, but when we need to get pages for example
/p/all_articles/user/ABC/page/2
/index.php?p=all_articles&user=ABC&page=2
we have tried
rewrite ^/p/all_articles/user/(.*)/pg(?:/([0-9]+))?$ /index.php?p=all_articles&user=$1&pg=$2 last;
this only works when we place in separate location block
location /page/all_articles {
rewrite ^/p/all_articles/user/(.*)/pg(?:/([0-9]+))?$ /index.php?p=all_articles&user=$1&pg=$2 last;
try_files $uri $uri/ /index.php;
}
and when done so, it would not let
/p/all_articles/user/ABC
to load.
also, search result pages would not work at all.
another issue we came across is on folder .htaccess
Order deny,allow
Deny from all
Options -Indexes
Under apache this would prevent any access to that folder and files except for php script. We tried,
location /(data|img)/ {
deny all;
return 404;
}
It does block the access to folder but, if you specify the filename, it will still serve, without denying access for example;
/data/backup_01012020.zip under apache .htaccess, only certain users were allowed to access this, while logged. and outside of it, apache will deny any access. But under nginx eventhough it gives 404 when trying to access /data/. Even when you are not logged, it would serve backup_01012020.zip file right away.
Now we can not figure out what we can do, which used to be piece of cake with apache. Our application is based on PHP and index.php is capable of handling all clean URL requests. It could have been great if Nginx simply pass all requests to index and let it handle instead of plenty of rewrites and location blocks. Any help would be great.