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

Become a contributor for community

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

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.