skip to Main Content

I have an old .htaccess file I’m trying to get working again but I don’t recall how I got it to work originally.

RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) $1.php

It is located like so:

/ localhost
  / site
    / subfolder
    / subfolder2
    / subfolder3
    / index.php
    / page.php
    / .htaccess

My website’s entry point is localhost/site/index.php and contains links to other pages. If I click on a link, say, ./page, it brings me to localhost/page instead of localhost/site/page.php. Note the subdirectory is ignored and the extension is taken literal when RewriteBase should have interpreted it as a .php.

I’ve tried changing RewriteBase / to RewriteBase /site/ and it doesn’t seem to do anything. Any ideas?

2

Answers


  1. Have this code in site/.htaccess:

    DirectoryIndex index.php
    RewriteEngine on
    
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{DOCUMENT_ROOT}/site/$1.php -f
    RewriteRule ^(.+?)/?$ $1.php [L]
    

    In site root .htacess you need to put this rule:

    RewriteEngine on
    
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{DOCUMENT_ROOT}/site/$1.php -f
    RewriteRule ^(.+?)/?$ site/$1.php [L]
    

    PS: It would be better to fix your relative links by adding this just below <head> tag of your page’s HTML: <base href="/site/" />

    Login or Signup to reply.
  2. An explanation…

    If I click on a link, say, ./page, it brings me to localhost/page instead of localhost/site/page.php

    It would have internally rewritten the request to /page.php (in the document root), which would have presumably resulted in a 404. This is because of the RewriteBase / directive – which provides the URL-prefix for relative path substitutions, ie. $1.php.

    Note the subdirectory is ignored …

    Because the .htaccess file is inside the /site subdirectory, the RewriteRule pattern only captures the part of the URL-path that comes after this. So, for example, if you request localhost/site/page (the resolved URL-path from your relative ./page link) then the RewriteRule pattern captures page (the value of the $1 backreference), which is rewritten to page.php, to which the RewriteBase is prefixed to become /page.php (in the document root).

    I’ve tried changing RewriteBase / to RewriteBase /site/ and it doesn’t seem to do anything. Any ideas?

    Yes. In fact, this is all you needed to do.

    Or, preferably, remove the RewriteBase directive entirely (which is what @anubhava did in his answer), since the .htaccess file resides in the same directory. In the absence of the RewriteBase directive, the default action for relative path substitutions is to add back the directory-prefix (ie. the file system path of the /site directory). So, given a request for /site/page (from the ./page link) it would naturally rewrite to /site/page.php without having to explicitly include the /site subdirectory.

    Either way, changing the RewriteBase directive, in this case, must have done something. If not, then you were probably seeing a cached response.

    My website’s entry point is localhost/site/index.php

    Providing the /site subdirectory is part of the visible URL, as you suggest, then the additional .htaccess file in the site root is not required (as in @anubhava’s answer). Either way, you wouldn’t need both.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search