Question

Apache - remove .php and .html file extensions using mod_rewrite in httpd.conf

Running Apache 2 on Ubuntu 14.04. rewrite_module is enabled (sudo apachectl -M).

In /etc/apache2/apache2.conf (the Ubuntu version of httpd.conf) I have the following code block:

<Directory /var/www/>
    <IfModule mod_rewrite.c>
        RewriteEngine On

        RewriteCond /%{REQUEST_FILENAME}.php -f
        RewriteRule ^([a-zA-Z0-9_-\s]+)/$ /$1.php

        RewriteCond /%{REQUEST_FILENAME}.html -f
        RewriteRule ^([a-zA-Z0-9_-\s]+)/$ /$1.html
    </IfModule>

    <IfModule mod_expires.c>
        ...

        <IfModule mod_headers.c>
            ...
        </IfModule>
    </IfModule>
</Directory>

Ran sudo service apache2 restart.

When I visit a url on my server without the .php file extension, I get a 404! Why isn’t this working?


Submit an answer


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Sign In or Sign Up to Answer

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

KFSys
Site Moderator
Site Moderator badge
June 15, 2023
Pinned Answer

Heya,

Your current rules have a few issues which are probably causing them to not work as expected.

  1. Your regular expression includes a trailing slash (/$), which means it only matches URLs that end with a slash. This may not be what you want.

  2. The %{REQUEST_FILENAME} variable contains the full filesystem path to the file or script matching the request. You are appending .php and .html to this variable, but then you are comparing it to the root directory because of the leading slash.

Here’s how you can rewrite your rules:

<Directory /var/www/>
    <IfModule mod_rewrite.c>
        RewriteEngine On

        # For PHP files
        RewriteCond %{REQUEST_FILENAME}.php -f
        RewriteRule ^(.*)$ $1.php [L]

        # For HTML files
        RewriteCond %{REQUEST_FILENAME}.html -f
        RewriteRule ^(.*)$ $1.html [L]
    </IfModule>

    <IfModule mod_expires.c>
        ...
        <IfModule mod_headers.c>
            ...
        </IfModule>
    </IfModule>
</Directory>

Note:

  • The [L] flag causes mod_rewrite to stop processing the rule set, which is useful for handling multiple rewrite conditions.

  • ^(.*)$ will match any character except newline, which should cover all URLs.

  • %{REQUEST_FILENAME} is replaced with $1, which in this context is the actual requested URL.

After making these changes, make sure to restart Apache:

sudo service apache2 restart

Please ensure your server allows .htaccess overrides or the <Directory> directive in the server configuration for these mod_rewrite rules to take effect.

Also, these rules will enable extensionless URLs, but they do not enforce them, meaning that the URL with the .php or .html extension will still be accessible. If you want to enforce extensionless URLs (i.e., redirect .php or .html URLs to extensionless ones), you’ll need additional rules.

Try this instead:

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

PLEASE HELP WITH THIS GUYS

<VirtualHost *:80>
        ServerAdmin www.calvano.com
        ServerName calvano.com
        ServerAlias www.calvano.com
        DocumentRoot "C:/project/htdocs/amado"
        <Directory />
                Options FollowSymLinks
                AllowOverride All
				<IfModule mod_rewrite.c>
					RewriteEngine On
					
					RewriteCond %(REQUEST_FILENAME) -d
					RewriteCond %{REQUEST_FILENAME}.php -f
					RewriteRule (.*) $1.php [L]
					RewriteCond %{REQUEST_FILENAME}.html -f
					RewriteRule (.*) $1.html [L]
                                        RewriteCond %(REQUEST_FILENAME) !-f
		
                                        RewriteRule ^furniture/([a-z0-9]+)$ furniture/item-detail.php?varton=$1 [L]
				</IfModule>
        </Directory>
        
</VirtualHost>

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel