1

I'm using this .htaccess that pass everything after URL to $param, so example.com/news/id goes to PHP as $_GET['param']='news/id'. But Nginx is always throwing me to 404 page.

My .htaccess:

RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule  (.*) index.php?param=$1

What I tried in Nginx default.conf:


server {
        listen 80;
        listen [::]:80;
    server_name domain.com;
        root    /var/www/html;

        location / {
                if (!-f $uri){
                        set $rule_0 1$rule_0;
                }
                if (!-d $uri){
                        set $rule_0 2$rule_0;
                }
                if ($rule_0 = "21"){
                rewrite ^(.*) index.php?param=$1;
                }
        }
}
MrWhite
  • 11,643
  • 4
  • 25
  • 40

2 Answers2

1

You don't use if here at all, nor do you manually check for the existence of files. This common pattern is handled instead by try_files.

For example:

location / {
    try_files $uri $uri/ /index.php?param=$uri;
}

(If your web app is broken and can't handle the leading / in the URI, fix the web app if possible, or see this question if not.)

Michael Hampton
  • 237,123
  • 42
  • 477
  • 940
  • I tried this but no success. Even if I try to reach /index.php directly nginx shows a 404 page. And the webapp is handling this properly, stopping nginx and starting httpd it works. – Sandro Benevides May 20 '19 at 02:19
  • @SandroBenevides Then you have some other problem. Check your error log. – Michael Hampton May 20 '19 at 02:21
  • @SandroBenevides A possible difference here is that the Nginx `$uri` variable contains a slash prefix, whereas the Apache `$1` backreference in the `.htaccess` directive does not. However, you should be able to see that by examining the value of the `param` URL parameter? Or are you saying your script is not being called at all? – MrWhite May 20 '19 at 10:44
  • @MrWhite If I comment this rule in location / block and access domain.com it works, and the script is doing its job properly. If I access domain.com/index.php, it shows 404 error and also if I try domain.com/news/id I get 404. I also tested sending a php file with echo phpinfo() and named as index, when trying to reach the file index.php it shows 404 error, if accessing just the domain.com it works. Other files as images I can access normally. – Sandro Benevides May 20 '19 at 14:06
1

I could fix it using these rules:

server{
try_files $uri $uri/ @rewrite;
  location @rewrite {
  rewrite ^/(.*)$ /index.php?_url=$1;
  }
}

If you have location / { } without any instructions inside, remove it.

  • See also https://stackoverflow.com/questions/41908851/nginx-conf-how-to-remove-leading-slash-from-uri – MrWhite May 20 '19 at 20:26