I am having problems creating a rewrite rule that match my .htaccess on Nginx, I am hoping someone can point me to the right direction.
My .htaccess
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php|robots\.txt|app|assets|upload|api)
RewriteRule ^([^/]+)(?:/([^/]+)|)(?:/([^/]+)|)(?:/([^/]+)|) index.php?class=$1&action=$2¶m=$3 [L]
My nginx configuration
location / {
rewrite ^/([^/]+)(?:/([^/]+)|)(?:/([^/]+)|)(?:/([^/]+)|) /index.php?class=$1&action=$2¶m=$3 break;
}
Query params are optional for example:
site.com/
site.com/customers
site.com/customers/add
site.com/customers/edit/1
I cannot rewrite the app code since iam only migrating from apache to nginx.
Any help will be appreciated.
Thanks.
You could structure the solution like this:
root /path/to/root;
index index.php;
location / {
try_files $uri $uri/ #rewrite;
}
location #rewrite {
rewrite ^/([^/]+)(?:/([^/]+)|)(?:/([^/]+)|)(?:/([^/]+)|) /index.php?class=$1&action=$2¶m=$3 last;
return 404;
}
location ~ \.php$ {
try_files $uri =404;
# fastcgi stuff
}
I have not checked your regular expression. The try_files directive is documented here.
Related
How to convert below condition for nginx,
RewriteEngine on
RewriteRule ^([^\.]+)/?$ index.php?$1 [L]
RewriteRule ^([^\.]+)/([^\.]+)/$ index.php?$1 [L]
RewriteRule ^([^\.]+)/([^\.]+)$ index.php?$1 [L]
RewriteRule ^([^\.]+)/([^\.]+)/([^\.]+)$ index.php?$1 [L]
RewriteRule ^([^\.]+)/([^\.]+)/([^\.]+)/$ index.php?$1 [L]
RewriteRule ^([^\.]+)/([^\.]+)/([^\.]+)/([^\.]+)$ index.php?$1 [L]
RewriteRule ^([^\.]+)/([^\.]+)/([^\.]+)/([^\.]+)/$ index.php?$1 [L]
I need to convert the apache .htaccess to Nginx configuration, if anyone knows the solution please help me, thanks.
Already I have converted .htaccess file to Nginx configuration by using some online tools, but it's not working.
If I put the URL in the browser automatically downloaded the index.php file. I have checked info.php but fpm also working fine. I don't know how to fix this issue.
here i have mention my Nginx conf file:
server {
server_name example.com;
root /home/example/public_html;
index index.php;
access_log /var/log/nginx/example/example-access.log;
error_log /var/log/nginx/example/example-error.log;
location / {
rewrite ^/([^\.]+)/?$ /index.php?$1 break;
rewrite ^/([^\.]+)/([^\.]+)/$ /index.php?$1 break;
rewrite ^/([^\.]+)/([^\.]+)$ /index.php?$1 break;
rewrite ^/([^\.]+)/([^\.]+)/([^\.]+)$ /index.php?$1 break;
rewrite ^/([^\.]+)/([^\.]+)/([^\.]+)/$ /index.php?$1 break;
rewrite ^/([^\.]+)/([^\.]+)/([^\.]+)/([^\.]+)$ /index.php?$1 break;
rewrite ^/([^\.]+)/([^\.]+)/([^\.]+)/([^\.]+)/$ /index.php?$1 break;
}
location ~ ^/(?:\.htaccess) {
deny all;
}
location ~ [^/]\.php(/|$) {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/php5.6-fpm-example.com.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
The GetPageSpeed converter provides the correct result:
server {
server_name example.com;
rewrite ^/([^\.]+)/?$ /index.php?$1 last;
rewrite ^/([^\.]+)/([^\.]+)/$ /index.php?$1 last;
rewrite ^/([^\.]+)/([^\.]+)$ /index.php?$1 last;
rewrite ^/([^\.]+)/([^\.]+)/([^\.]+)$ /index.php?$1 last;
rewrite ^/([^\.]+)/([^\.]+)/([^\.]+)/$ /index.php?$1 last;
rewrite ^/([^\.]+)/([^\.]+)/([^\.]+)/([^\.]+)$ /index.php?$1 last;
rewrite ^/([^\.]+)/([^\.]+)/([^\.]+)/([^\.]+)/$ /index.php?$1 last;
}
Note the last directive. This is correct. It will make sure NGINX will start location search again to see which directives are applicable to rewritten URI /index.php. Then it finally ends up in your location ~ [^/]\.php(/|$) { ... } and directives for processing with PHP-FPM will apply.
With break, things will not work, because there's no new location search after rewriting URL. The URI stays /index.php but directives from location ~ [^/]\.php(/|$) { ... } will not be applied because NGINX didn't "go to" apply directives from it.
UPDATE 2022-03-18
As pointed out by #Danila Vershinin the rewrite statements should end with last instead of break.
You can try something like this
location / {
rewrite ^/([^\.]+)/?$ /index.php?$1 break;
rewrite ^/([^\.]+)/([^\.]+)/$ /index.php?$1 break;
rewrite ^/([^\.]+)/([^\.]+)$ /index.php?$1 break;
rewrite ^/([^\.]+)/([^\.]+)/([^\.]+)$ /index.php?$1 break;
rewrite ^/([^\.]+)/([^\.]+)/([^\.]+)/$ /index.php?$1 break;
rewrite ^/([^\.]+)/([^\.]+)/([^\.]+)/([^\.]+)$ /index.php?$1 break;
rewrite ^/([^\.]+)/([^\.]+)/([^\.]+)/([^\.]+)/$ /index.php?$1 break;
}
or use a converter or another converter.
apache .htaccess
<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L]
</IfModule>
Please help me. This problem has bothered me for 3 days. Thank you very much
I try to convert it into the following
if (!-e $request_filename){
rewrite ^/(.*)$ /index.php/$1 last;
}
Authorization cannot be obtained correctly on nginx,Can cause CORS problems
I think it's because this sentence hasn't been converted successfully
RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
because I don't know how to convert it
Please help me
I expect to get the converted nginx htaccess
The .htaccess you're seeking to convert is quite standard "front controller" pattern. What it does is, for any URI, it will attempt to:
serve the file matching the exact URI
if the file wasn't found in the previous step, then check a directory, and attempt to serve from there (subject to index directives or further rewrites)
if the directory wasn't found, route the request to index.php
The de-facto standard NGINX snippet that does the same, utilizes try_files directive.
You'll find this used for virtually all PHP-based CMS configs for NGINX:
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
The try_files directive, similar to if when being checked for file existence, has its performance pitfalls, so in fact, you may want to do as the article says is route unconditionally all request via PHP-FPM by default, then some (e.g. static assets) served by NGINX directly. Example bare-bones config for WordPress which illustrates the idea:
index index.html index.php;
location / {
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
include fastcgi_params;
# override SCRIPT_NAME which was set in fastcgi_params
fastcgi_param SCRIPT_NAME /index.php;
fastcgi_pass unix:/var/run/php-fpm/example.com.sock;
}
location /wp-content/ { }
In this case /wp-content/ is allocated as an empty location in order to ensure NGINX does not pass requests to files in it via PHP-FPM. It will serve everything directly for static files.
Thus the URL rewriting is actually eliminated, and all the performance penalty that comes with it is negated.
This is the answer
if (!-f $request_filename) {
rewrite ^(.*)$ /index.php?s=/$1 last;
break;
}
if (!-d $request_filename) {
rewrite ^(.*)$ /index.php?s=/$1 last;
break;
}
I have .htaccess:
RewriteRule ^thumb/(.*)x(.*)/r/(.*) thumb.php?w=$1&h=$2&src=$3
RewriteRule ^medias/(.*) files.php?file=$1
RewriteRule ^sitemap\.xml$ index.php [L]
RewriteRule ^(.*)(\.html|\.htm)$ index.php [L]
RewriteRule ^(.*)(\.rss|\.atom|\.txt)$ index.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/?$ index.php [L]
Nginx rewriting is:
rewrite ^/thumb/(.*)x(.*)/r/(.*) /thumb.php?w=$1&h=$2&src=$3;
rewrite ^/medias/(.*) /files.php?file=$1;
rewrite ^/sitemap\.xml$ /index.php break;
rewrite ^/(.*)(\.html|\.htm)$ /index.php break;
rewrite ^/(.*)(\.rss|\.atom|\.txt)$ /index.php break;
When accessing categories, I get the home page.
Any help please
Thanks
Nginx configuration is typically approached a bit differently, with lots of location blocks.
It's difficult for me to test this, but this might help you forward:
# Nginx excludes the query string (part after the ?) before trying to match
location = /index.php {
# FastCGI PHP stuff here
}
location ~ ^/thumb/([^/]+)x([^/]+)/r/([^/]+) {
rewrite ^ /thumb.php?w=$1&h=$2&src=$3 break;
}
location ~ ^/medias/(.*) {
rewrite ^ /files.php?file=$1 break;
# To be honest I would try to avoid serving files through PHP. It's much more efficient to let Nginx serve them directly with something like:
root /path/to/media's/parent;
try_files $uri =404;
}
location ~ ^/sitemap\.xml$ {
rewrite ^ index.php break;
}
location ~ (\.html|\.htm|\.rss|\.atom|\.txt)$ {
rewrite ^ index.php break;
}
# Catch-all
location / {
try_files $uri index.php;
}
The fact that you have to test for extensions, with regexes, means they kind of all have to use regexes. That's because those blocks with regexes are evaluated before longest-prefix blocks. Make sure to read Nginx' documentation about location blocks for a better explanation, with examples.
I have this Nginx rule:
location /fr {
rewrite ^/(fr)(?:/([^/]+))?$ /$2?lang=$1 last;
}
I have pages such as:
example.com/en/some-page
example.com/fr/some-page
example.com/fr
...
But I also have a page which starts by fr:
example.com/free-plan // doesn't work
example.com/fr/free-plan // doesn't work either
How can I modify my Nginx rule so that the /fr rule doesn't interference with my free-plan page?
Ps: I use PHP and rules to service page without the extension:
location / {
try_files $uri $uri.html $uri/ #extensionless-php;
}
location #extensionless-php {
rewrite ^(.*)$ $1.php last;
}
I would suggest that you treat /fr as a special case and use location /fr/ to avoid side-effects from pages that begin with fr.
For example:
location = /fr {
rewrite ^/(.*)$ /?lang=$1 last;
}
location /fr/ {
...
}
See this document for details.
URL rewrite is not working in Nginx and operating system is Ubuntu 12.4 Lts
when open http://mvc.loc it is working
but when i try to open http://mvc.loc/login Not working
404 Not Found
nginx/1.1.19
.htaccess
<IfModule !mod_rewrite.c>
ErrorDocument 500 "mod_rewrite must be enabled"
</IfModule>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?u=$1
virtual hosts for mvc.loc
server {
listen 80;
server_name mvc.loc;
access_log /var/log/nginx/mvc.loc.access.log;
error_log /var/log/nginx/mvc.loc.error.log;
root /usr/share/nginx/www/mvc;
index index.php;
# use fastcgi for all php files
# Are you sure you have this set up?
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# deny access to apache .htaccess files
location ~ /\.ht {
deny all;
}
}
location / {
rewrite ^(.*)$ /index.php?u=$1 last;
}
Well #NanheKumar's answer got the rewrite correct but it ignored the first 2 rules in the htaccess
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
This means check if the request doesn't match a file and doesn't match a directory, to imitate this exact behavior you can use try_files like this
location / {
try_files $uri $uri/ /index.php?u=$request_uri;
}
This will make sure to serve requests that point to an asset or a directory directly first then if neither it would pass the request to index.php
EDIT: unless index.php is able to serve assets, this will cause all assets ( images, css, javascript, etc ) to show errors because index.php will be receiving arguments it's not expecting. Think about something like this http://example.com/index.php?u=/images/background.jpg