You don't actually "hide" the extension using .htaccess
(if that is what you are expecting). You must first remove the .php
extension in your HTML source, in your internal links (Apache/.htaccess
should not be used to do this). The extension is now "hidden" (but the links don't work).
You then use .htaccess
to internally rewrite the extensionless URL back to the .php
extension in order to make the URL "work".
For example:
RewriteEngine On
# Rewrite to append ".php" extension if the file exists
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule (.+) $1.php [L]
Given a request for /home
, the above will internally rewrite the request to /home.php
if home.php
exists as a physical file in the document root.
Note that this rule does assume your URLs do not end in a slash. eg. It expects /home
and not /home/
. if you request /home/
then it will result in a 404, since /home/.php
does not exist.
The preceding condition first checks that the requested URL + .php
exists as a physical file before rewriting the request. This is necessary in order to prevent a rewrite loop (500 error).
If your URLs do not contain dots (that are otherwise used to delimit the file extension) then the above can be optimised by excluding dots in the matched URL-path. ie. Change the RewriteRule
pattern from (.+)
to ^([^.]+)$
. This avoids your static resources (.css
, .js
, .jpg
, etc.) being unnecessarily checked for the corresponding .php
file.
If you are changing an existing URL structure that previously used the .php
extension and these URLs have been indexed by search engines and/or linked to by third parties then you should also redirect requests that include .php
in order to preserve SEO. This redirect should go before the above rewrite, immediately after the RewriteEngine
directive:
# Redirect to remove ".php" extension
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.+)\.php$ /$1 [R=301,L]
The preceding condition that checks against the REDIRCT_STATUS
environment variable ensures that only direct requests are stripped of the .php
extension and not rewritten requests by the later rewrite (which would otherwise result in a redirect loop).
NB: Test with a 302 (temporary) redirect first to avoid potential caching issues.
RewriteRule ^(.*?)/(.*?)/(.*?)$ $1.php?$2=$3 [L]
This does considerably more than simply "removing" (or rather "appending") the .php
extension.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^(.*)$ $1.php
</IfModule>
This will result in a rewrite-loop, ie. a 500 Internal Server Error response as it will repeatedly append the .php
extension again and again to the same request.
(The <IfModule>
wrapper is not required.)