Pass URL component/path to PHP with Nginx
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:
- https://stackoverflow.com/questions/9641603/remove-parameters-within-nginx-rewrite (Not exactly what I'm after, speaks to removing additional $args)
- https://stackoverflow.com/a/40334028/1171790 (I tried this solution by replacing 'location' with an empty string but it doesn't seem to pass the param to PHP)
- https://serverfault.com/a/488480/325456 (I'm unclear what my regex should be after rewrite. This answer uses just '^'. This seems too broad if I want to still serve my static files/directories)
- https://serverfault.com/a/542550/325456 (This seemed closest to what I am looking for, but copy/pasting the code and replacing the filename/values with my own still didn't work for me)
If someone with a better knowledge of Nginx than I could help me out, I would be eternally grateful.
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;
}
}
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;
}