Skip to main content

Web Development

Remove .php and .html Extensions via .htaccess

·

Terminal window showing .htaccess mod_rewrite rules for removing PHP and HTML file extensions from Apache URLs

Removing .php or .html from a URL turns example.com/index.php into example.com/index. Apache's mod_rewrite handles this in a few lines inside .htaccess. The result: cleaner URLs that are easier to share and easier for users to type.

What is an .htaccess file?

Apache .htaccess configuration file open in a text editor showing mod_rewrite directives

.htaccess is an Apache server configuration file placed in a directory. It controls that directory's behaviour without touching the main server config. Key facts:

  • It is a plain text file with no filename, only an extension: .htaccess, not file.htaccess.
  • It works only on servers running Apache HTTP Server.
  • Settings in .htaccess apply to the directory it sits in, plus every subdirectory beneath it.

What .htaccess can control

.htaccess handles a range of server behaviours:

  • MIME type definitions
  • Custom error pages (404, 500, etc.)
  • Password protection on directories
  • Blocking specific IP addresses or bot user-agents
  • Preventing directory listing
  • Blocking hotlinked images
  • Redirecting URLs
  • Changing the default directory index page

Removing the .php or .html extension

Place .htaccess in the root of your site (or the subdirectory you want to affect), then add the block below. The comment on line 4 shows how to adapt it for .html files.

<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME}.php -f
  RewriteRule ^(.*)$ $1.php [L]
</IfModule>

To strip .html instead, replace every .php reference with .html:

<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME}.html -f
  RewriteRule ^(.*)$ $1.html [L]
</IfModule>

What each directive does:

  • RewriteEngine on activates mod_rewrite for this directory.
  • RewriteCond %{REQUEST_FILENAME} !-d skips the rule when the request matches a real directory.
  • RewriteCond %{REQUEST_FILENAME}.php -f proceeds only when a .php file with that name actually exists on disk.
  • RewriteRule ^(.*)$ $1.php [L] rewrites the bare URL internally to the .php file, without changing what the browser sees. The [L] flag stops further rule processing.

Testing the rewrite

Create a file called test.php in the same directory as .htaccess, with this content:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Extension removal test</title>
  </head>
  <body>
    <h1>test.php loaded via <a href="test">example.com/test</a></h1>
  </body>
</html>

Visit example.com/test in a browser (no .php). If the page loads, the rewrite works. The anchor text in the page uses the bare URL, so clicking it confirms round-trip behaviour.

Adding a trailing slash

To enforce URLs like example.com/index/ instead of example.com/index, use the block below. Swap .php for .html if your files use the HTML extension.

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/$ $1.php [L]
RewriteRule ^([^/]+)/([^/]+)/$ /$1/$2.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ /$1/ [R=301,L]

The [R=301,L] on the last rule issues a permanent redirect, which tells search engines and browsers to update their records to the slash-terminated form.

If you work with PHP regularly, 13 PHP Tips That Make Development Faster covers error handling, PDO, and other practical patterns. 7 Popular PHP Frameworks Compared breaks down Laravel, Symfony, and five others by architecture and use case.

For broader web programming help, see Do My Programming Homework.

Share: X / Twitter LinkedIn

Related articles

← All articles

Stuck on a programming assignment?

Get expert help in Java, C++, Python, JavaScript, SQL, and more. We deliver working code with a clear walkthrough so you can understand and defend it.