Nino
Nino

Reputation: 23

htaccess to rewrite url in order to remove php extension only at the root directory and not in subdirectories

I have a website composed as follows:

index.php
page1.php
page2.php
page3.php
 - images
   image1.jpg
   image2.jpg
 - style
   style.css

I want to write an htaccess file which can give me SEO friendly URL. In example:

and also:

But I would like to apply those rules only on the first directory, so "images" and "style" dirs can continue to be reached using the extensions.

Can somebody help? Thanks

Upvotes: 2

Views: 1164

Answers (1)

MrWhite
MrWhite

Reputation: 45829

  1. You should already be linking to the files without the .php extension on your internal URLs (ie. href="/page1", not href="/page1.php"). I'm also assuming that your URLs don't otherwise contain dots (which normally delimits the file extension).

  2. Implement a rewrite to append the .php extension if required. This needs to go near the top of the root .htaccess file:

    RewriteEngine On
    
    # Internally rewrite extenionless URLs to append ".php" if required
    # Tests only requests (that do not contain a dot) in the root directory
    RewriteCond %{DOCUMENT_ROOT}/$1.php -f
    RewriteRule ^([^./]+)$ $1.php [L]
    

    Alternative for the RewriteCond (filesystem check):

    RewriteCond %{REQUEST_FILENAME}.php -f
    :
    

    Alternatively, you could remove the RewriteCond directive altogether to unconditionally rewrite all requests in the root (without a file extension) to append the .php extension.

  3. (OPTIONAL) If you are changing a URL structure and removing .php from your URLs and the old URLs have been indexed by search engines and/or linked to by third parties then you need to also implement a redirect to remove the .php extension for SEO.

    Add the following immediately after the RewriteEngine directive above (before the internal rewrite):

    # Redirect to remove the `.php` extension inbound requests
    # Only affects the root directory
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteRule ^([^./]+)\.php$ /$1 [R=301,L]
    

    The condition that tests against the REDIRECT_STATUS environment variable ensures we don't redirect already rewritten requests by the later rewrite and this avoiding a redirect loop.

    NB: Test first with a 302 (temporary) redirect to avoid potential caching issues.

  4. Alternatively (instead of #3), to prevent direct access to the .php file and serve a 404 Not Found instead then add the following immediately after the RewriteEngine directive above (before the internal rewrite):

    # Prevent direct access to ".php" file and serve a 404 instead
    # Only affects the root directory
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteRule ^([^./]+)\.php$ - [R=404]
    

what is the best way to show the content of my custom 404 page every time a 404 error occurs? (I would not like to use redirect)

Use the following at the top of the .htaccess file, passing the full URL-path to the ErrorDocument directive.

ErrorDocument 404 /error-docs/e404.php

The stated error document is called using an internal subrequest (there is no external redirect).

Note that this should include the .php file extension here - this is entirely invisible to the user.

Upvotes: 3

Related Questions