Search code examples
phpapache.htaccessmod-rewrite

Rewrite rule to hide extension .htaccess


I am trying to hide the extension of .php file from the link

for example www.example.com/about.php To display www.example.com/about

what I did

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [NC,L] 

and It works perfectly.

but I have another link which example.com/news.php?id=45 according to the above rule, I can access the link like

example.com/news?id=45 without .php

but I want to hide id=45 I want it like this example.com/news/45

what I did RewriteRule ^news.php?id=([0-9]+) /news/$1 [NC,L]

But It won't work I got 500 Internal Server Error


Solution

  • Try it like this instead:

    # MultiViews must be disabled for "/news/45" to work
    Options -MultiViews
    
    RewriteEngine on
    
    # Rewrite "/news/45" to "news.php?id=45"
    RewriteRule ^news/(\d+)$ news.php?id=$1 [L]
    
    # Handle extensionless ".php" URLs
    RewriteCond %{REQUEST_URI} !\.\w{2,3}$
    RewriteCond %{DOCUMENT_ROOT}/$1.php -f
    RewriteRule (.*) $1.php [L]
    

    Your 500 Internal Server Error was actually caused by your original directives that "hide" the .php extension, not your "new" directive (that wasn't actually doing anything). Your original directives would have rewritten a request for /news/45 to /news/45.php to /news/45.php.php etc. creating a rewrite-loop (500 error).

    See my answer to the following question on ServerFault with a detailed explanation of this behaviour: https://serverfault.com/questions/989333/using-apache-rewrite-rules-in-htaccess-to-remove-html-causing-a-500-error

    what I did RewriteRule ^news.php?id=([0-9]+) /news/$1 [NC,L]

    But It won't work I got 500 Internal Server Error

    The logic of this directive is reversed and would never actually match the requested URL (or anything for that matter), so won't actually do anything. It is, however, syntactically OK, so won't trigger an error.

    The 500 error would have occurred simply by requesting /news/45 (with your original directives), whether this directive was in place or not.