Home > Back-end >  .htaccess mod_rewrite working ONLY with HTML, not with my PHP files
.htaccess mod_rewrite working ONLY with HTML, not with my PHP files

Time:02-02

I've just finished setting up my first app on localhost - and the .htaccess working incredibly fine. I just uploaded the files to Google Cloud LAMP Server, set up the database & got everything working -- however, for some reason the PHP files are not being located (?) which is strange because it's working in localhost just fine, and HTML files seem to be rewrited just fine as well! Here's the error log in apache:

Negotiation: discovered file(s) matching request: /var/www/html/index (None could be negotiated).

Here's my .htaccess:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [NC,L]
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.*)$ $1.html [NC,L]

What is strange is that it's rewriting HTML with no problem but PHP files will throw this:

Not Found
The requested URL was not found on this server.

I tried pretty much everything:

  • Changed /etc/apache2/apache2.conf
  • Changed /etc/apache2/sites-available/000-default.conf
  • Made sure that 'a2enmod rewrite' is enabled

Still, getting

Not Found
The requested URL was not found on this server.

CodePudding user response:

If looks as if MultiViews is enabled, but .php files are not a permitted extension. MultiViews needs to be disabled for your mod_rewrite rules to be processed successfully. To disable MultiViews, add the following to the top of the .htaccess file:

Options -MultiViews

MultiViews is disabled by default, however, it is explicitly enabled (in the server config) on some distros.


Aside:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [NC,L]
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.*)$ $1.html [NC,L]

The first condition that checks that the request does not map to a directory is entirely redundant.

The condition that checks whether the corresponding .php (or .html) file exists is not necessarily checking that the same "file" you are rewriting to. If, for instance, you requested /foo/bar and foo.php happened to exist then you will get a rewrite-loop (500 Internal Server Error). To resolve this issue, it should be rewritten like this instead:

RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule (.*) $1.php [L]

The NC flag was superfluous, as was the anchors surrounding the RewriteRule pattern.

  • Related