1

I have wordpress installed in the root directory of the domain.

I am using pretty links and fast cgi caching.

Now I have a directory inside the root directory (e.G. "/course/") that contains some .php files that have nothing to do with wordpress. I would love to access these files without the .php extension.

On another server where everything is setup inside the root directory and I don't use wordpress its working with these additions to the server block:

    location / {
            try_files $uri $uri.html $uri/ @extensionless-php;
    }

    location @extensionless-php {
            rewrite ^(.*)$ $1.php last;
    }

I am struggeling to get it working on my wordpress server. Maybe I am missing something, here is the complete server block:

server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    root /var/www/html;
    index index.php index.html index.htm;

    client_max_body_size 10M;

    server_name example.com www.example.com;

    location ~* "^/something" {
            rewrite ^ http://example.com/curso-gratis-habitos/$ $1?ref=conlasalud permanent;
    }

    location ~* "^/some-other-thing" {
            rewrite ^ https://someotherurl.com/? permanent;
    }

    location ~* "^/something-else" {
            rewrite ^ https://someotherurl.com/? permanent;
    }

    location ~* "^/another-one" {
            return 301 https://someotherurl.com/;
    }

    location ~* "^/special-url" {
            return 301 https://someotherurl.com/;
    }

    set $cache_uri $request_uri;

    # POST requests and urls with a query string should always go to PHP
    if ($request_method = POST) {
            set $cache_uri 'null cache';
    }
    if ($query_string != "") {
            set $cache_uri 'null cache';
    }

    # Don't cache uris containing the following segments
    if ($request_uri ~* "(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php|wp-.*.php|/feed/|index.php|wp-comments-popup.php|wp-links-opml.php|wp-locations.php|sitemap(_index)?.xml|[a-z0-$
            set $cache_uri 'null cache';
     }

     # Don't use the cache for logged in users or recent commenters
    if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_logged_in") {
            set $cache_uri 'null cache';
    }

    location ~ \.php$ {
            try_files $uri @extensionless-php =404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass unix:/var/run/php5-fpm.sock;
            fastcgi_index index.php;
            include fastcgi_params;
    }

    # Use cached or actual file if they exists, otherwise pass request to WordPress
    location / {
            try_files /wp-content/cache/supercache/$http_host/$cache_uri/index.html $uri $uri/ /index.php @extensionless-php;
    }

    location @extensionless-php {
            rewrite ^(.*)$ $1.php last;
    }

}
5
  • have you tried using another server block where your root would point to root /var/www/html/course or wherever course is?
    – prosti
    Mar 15, 2016 at 22:44
  • No, I am not sure how this is supposed to work. What do I have to put in this server block? server { root /var/www/html/course; index index.php index.html index.htm; location / { try_files $uri $uri/ $uri.php $uri.html; } }
    – Snowball
    Mar 16, 2016 at 2:51
  • I think I can reach you with the example duping tomorrow, without duping it would be ramble, just in case the other solution not working...
    – prosti
    Mar 17, 2016 at 19:05
  • thanks, I still haven't find a solution. The one proposed by @tero-kilkanen doesn't works for me yet.
    – Snowball
    Mar 18, 2016 at 3:16
  • Still didn't found the error. @steve-e do you may know? Your answer really helped the last time I had a nginx config problem
    – Snowball
    Mar 22, 2016 at 11:32

2 Answers 2

1

The problem here most likely is that you have the location block for .php$ two times, and the second one of these blocks is never reached, since the first one matches all PHP files.

A simpler solution would be like this:

location ~ ^/course/(.+)$ |
    try_files $1.php $1;
}

and have no location @extensionless-php, second location ~ \.php$ blocks in the configuration.

This location block causes nginx to first look up for the URI itself for URIs startinc with /course/, and if one is not found, try to find the URI + .php extension. The filename with PHP extension is then passed to the normal PHP processing block. This block should be above the location ~ \.php$ {line, since otherwise that block is used always first.

7
  • what the "pretty links" mean I guess is "permalinks" structure in WordPress and this causes that URLs like example.com/course/abc are interpreted most likely as part of WordPress
    – prosti
    Mar 15, 2016 at 22:57
  • The original question stated explicitly that the files in /course/ have nothing to do with WordPress. Mar 15, 2016 at 23:02
  • I've tried your solution but it doesn't work. The server file above was pasted wrong, sorry for that. There is only one .php block in the configuration. Anyway when I remove the extensionless-php block and add yours above the .php block it still doesn't work. It shows the wordpress 404 page. There are some php files that have the same name as a wordpress page (e.G. example.com/course/thank-you) and if I try to access them I get actually redirected to wordpress example.com/thank-you instead of a 404. Maybe @prosti is right
    – Snowball
    Mar 16, 2016 at 2:50
  • If you added my location block below the location ~ \.php$ { entry, that is the reason for it not working. The ~ in the string forces nginx to stop trying to match any other rule, and use this rule. So, make sure that the block is above location ~ \.php$ { block. I modified the answer to include this detail. Mar 17, 2016 at 13:16
  • As I said, its above the .php location block and still not working as expected. Here is the actualized server block: jsfiddle.net/mp4e2kwf
    – Snowball
    Mar 18, 2016 at 3:14
0

Moving the location / under the location ~ \.php$ block and adding these additions below them finally worked for me:

        location ~ ^/course/(.+)$ {
                try_files $uri $uri/ @extensionless-php;
        }

        location @extensionless-php {
                rewrite ^(.*)$ $1.php last;
        }

Here is the complete server block for reference:

server {
        listen 80 default_server;
        listen [::]:80 default_server ipv6only=on;

        root /var/www/example.com/html;
        index index.php index.html index.htm;

        client_max_body_size 10M;

        server_name example.com;

        location ~* "^/something" {
                rewrite ^ http://example.com/curso-gratis-habitos/$ $1?ref=conlasalud permanent;
        }

        location ~* "^/some-other-thing" {
                rewrite ^ https://someotherurl.com/? permanent;
        }

        location ~* "^/something-else" {
                rewrite ^ https://someotherurl.com/? permanent;
        }

        location ~* "^/another-one" {
                return 301 https://someotherurl.com/;
        }

        location ~* "^/special-url" {
                return 301 https://someotherurl.com/;
        }

        set $cache_uri $request_uri;

        # POST requests and urls with a query string should always go to PHP
        if ($request_method = POST) {
                set $cache_uri 'null cache';
        }
        if ($query_string != "") {
                set $cache_uri 'null cache';
        }

        # Don't cache uris containing the following segments
        if ($request_uri ~* "(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php|wp-.*.php|/feed/|index.php|wp-comments-popup.php|wp-links-opml.php|wp-locations.php|sitemap(_index)?.xml|[a-z0-9_-]+-sitemap([0-9]+)?.xml)") {
                set $cache_uri 'null cache';
         }

         # Don't use the cache for logged in users or recent commenters
        if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_logged_in") {
                set $cache_uri 'null cache';
        }

        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                include fastcgi_params;
        }

        # Use cached or actual file if they exists, otherwise pass request to WordPress
        location / {
                try_files /wp-content/cache/supercache/$http_host/$cache_uri/index.html $uri $uri/ /index.php;
        }

        location ~ ^/course/(.+)$ {
                try_files $uri $uri/ @extensionless-php;
        }

        location @extensionless-php {
                rewrite ^(.*)$ $1.php last;
        }

        # Enable the hide backend feature - Security > Settings > Hide Login Area > Hide Backend
        rewrite ^(/)?somesecreturl/?$ /wp-login.php?$query_string break;

        # Protect System Files - Security > Settings > System Tweaks > System Files
        location ~ /\.ht { deny all; }
        location ~ wp-config.php { deny all; }
        location ~ readme.html { deny all; }
        location ~ readme.txt { deny all; }
        location ~ /install.php { deny all; }
        location ^wp-includes/(.*).php { deny all; }
        location ^/wp-admin/includes(.*)$ { deny all; }

        # Disable PHP in Uploads - Security > Settings > System Tweaks > Uploads
        location ^wp\-content/uploads/(.*).php(.?) { deny all; }

}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .