I'm not sure if I'm posting this in the correct place as this is related to nginx configuration and not specifically PHP scripts. If I am posting this in the wrong section, please let me know and I will post it in the correct location (unless a Mod is able to move threads?).

I'm configuring nginx on my server and I've got it mostly configured how I want. The last thing I need to do (for now) is remove ".php" from the URL if someone goes there. I have done some research on this but can only find information on making nginx search for "file.php" if the URL ends in "file" which is not what I want.

The information I can find mostly refers to the try_files directive and says to do this:

try_files $uri $uri.php;

This is not what I want though. What this does is if "mysite.com/something" doesn't exist, try loading "mysite.com/something.php" without writing .php to the URL. What I want is if someone goes to "mysite.com/somthing.php" to redirect them to "mysite.com/something" preferably with a 301 redirect. Reversing the above would not do anything because the $uri variable will contian ".php" if it's typed in to the address bar, making $uri.php become file.php.php.

This is very easy if I want to do it for specific files:

rewrite /page.php /page permanent;

The problem is that I want this to work for anything the end user may type.

I might be missing something very simple and trivial on how to do this. I doubt it's this simple, but does nginx have something similar to PHP's str_replace(); I could use to remove it?

I want this to happen even if the requested file exists. If more information is needed, let me know.

I cannot test right now, but try:

return 301 ^(.*)$ $1.php

Note that try_files is important because it will check if the script exists and will avoid some security issues, for example if somebody uploads a text file hell.txt and submit a request like this:

GET http://localhost/uploads/hell.txt/o.php 

If o.php does not exists, the parser will execute hell.txt as a PHP script, the same if the file is an image with an embedded script.


That return command gives me an error when I restart nginx to apply the changes:

nginx: [emerg] invalid number of arguments in "return" directive in /etc/nginx/conf.d/default.conf:19
nginx: configuration file /etc/nginx/nginx.conf test failed

Line 19 is your suggested code. I've put in within location / {} because you didn't specify where I need it.

Regarding try_files, I am using it for friendly URL's because I'm making my site dynamic by having just one page which loads content depending on the URL (E.g.: mysite.com/thispage will display the contents of mysite.com/index.php?page=thispage). The reason why I want to remove .php from the end is in case anyone accidentally (or even deliberately) puts .php at the end. My intention is to redirect [whatever].php to [whatever] before it starts trying to parse any PHP. Like the rewrite rule would do.

Currently, if you go to [something].php then the default 404 error page is coming up unless the file exists, in which case it runs that but I don't want it to do so.

Is what I'm trying even possible?