1

I recently switch from Apache to Nginx. I'm brand new to Nginx, so please be kind. One of my apps uses the first URL component as a query string unless the path/file exists - in which case Apache serves the file. Previously, I would pass PHP the first string in the URL path such as example.com/foo (where foo is passed). My old .htaccess looks like this:

<IfModule mod_rewrite.c>

   RewriteEngine On

   RewriteBase /

   # if file or directory exists, serve it   
   RewriteCond %{REQUEST_FILENAME} -f [OR]
   RewriteCond %{REQUEST_FILENAME} -d
   RewriteRule .* - [S=3]
   # if not, pass the url component to PHP as the "section" query string
   RewriteRule ^([^/]+)/?$ ?section=$1 [L]

</IfModule>

I've tried many things in Nginx but because I'm so new, I'm stuck. This seems to get me the closest to what I want:

server {

  root /var/www/mysite.com;

  index index.php;
  server_name www.mysite.com mysite.com;

  location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php7.0-fpm.sock;
  }

  location / {
    rewrite ^/(.*)$ /index.php?section=$1 break;
    try_files $uri $uri/ /index.php$args;
  }

}

Still, the query string doesn't seem to be passed to my index.php script.

I've reviewed these other questions:

If someone with a better knowledge of Nginx than I could help me out, I would be eternally grateful.

jonathanbell
  • 121
  • 1
  • 5
  • The rewrite with capture group looks ok. I wonder if the problem is that try_files is using $args is from the original request rather than the rewritten request. If that's the case I wonder if you could use [last](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite) instead of break. This probably doesn't solve the problem but might give you something else to consider. – Tim May 18 '17 at 21:16
  • Hey, that worked pretty well! I can see that my param is passed to PHP now and PHP can use it. However, nginx seems to be routing all requests to PHP (such as requests for static assets like CSS and JS) so I get 404's for URLs like http://example.com/dir1/dir2/image.jpg Do you have any further ideas? Should I just adjust my rewrite regex to exclude those files?? Seems like there's go to be something better than that. Is try files not working the way it should here? – jonathanbell May 18 '17 at 22:45

2 Answers2

1

I ended up using a named location. This functions, but I still feel like there's a better solution out there.

server {

  root /var/www/mysite.com;

  index index.php;
  server_name mysite.com;

  location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php7.0-fpm.sock;
  }

  location / {
    try_files $uri $uri/ @fallback;
  }

  location @fallback {
    rewrite ^/(.*)$ /index.php?section=$1 last;
  }

}
jonathanbell
  • 121
  • 1
  • 5
1

A more native way of doing this in nginx is:

server {
    root /var/www/mysite.com;
    index index.php;
    server_name example.com;

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    }

    location /(.*) {
        try_files $uri $uri/ /index.php?section=$1;
    }
Tero Kilkanen
  • 34,499
  • 3
  • 38
  • 58