Search code examples
apache.htaccessmod-rewrite

Use index.php as main file for subfolders - htaccess


By default my hosting provider doesn't uses the index.php file as the main file for the folders, so if I go to mydomain.com/dashboard/ for example, it says that the page doesn't exist, but when I go to mydomain.com/dashboard/index.php it works. I'm trying to solve this with the htaccess file and found a solution, but it doesn't work completely. This is because I have something else in my htaccess to remove the .php extension from the url's. If I remove this part, it does work, but then I have the .php extension on my url again, which I don't want. This is my htaccess:

RewriteEngine On

Options +FollowSymLinks

RewriteCond %{THE_REQUEST} ^.*/index.php
RewriteRule ^(.*)index.php$ https://www.example.com/$1 [R=301,L]

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

Could someone help me with this issue?


Solution

  • You need to set the DirectoryIndex (part of mod_dir) - this instructs Apache which file(s) to serve when requesting a directory. (The Apache default is index.html inside the requested directory only.)

    For example:

    DirectoryIndex index.php
    

    Reference:


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

    This unconditionally appends the .php extension to any request that does not map to a file. The "problem" with this is if you request a directory (assuming the URL-path does not contain a dot) then it will rewrite the request to /<directory>/.php which will likely result in a 404.

    If you are using extensionless URLs (and requesting directories directly) then you need to check that the target file exists before rewriting the request. For example:

    # Rewrite extensionless URL to ".php" file only if it exists
    RewriteCond %{DOCUMENT_ROOT}/$1.php -f
    RewriteRule ^([^.]+)$ $1.php [L]
    

    No need to backslash-escape literal dots in regex character class. And the NC flag is superfluous here.

    You should also make sure that MultiViews is disabled, otherwise your rule is bypassed. For example:

    Options +FollowSymLinks -MultiViews