[php] Redirect all to index.php using htaccess

I am writing a simple PHP-based MVC-ish framework. I want this framework to be able to be installed in any directory.

My PHP script grabs the request uri and breaks it off into segments. It makes segment 1 the controller and segment 2 the action. This goes all fine when I do this:

http://www.example.com/mvc/module/test/

It will go to the specific module controller and method. Now I have a default controller, the home controller, which is in folder home.

Now when I access this folder directly http://www.example.com/mvc/home/ It will display a 403 forbidden , because this folder does exist, instead it should also go back to http://www.example.com/mvc/index.php

If I would have installed the framework in a different folder, lets say folder framework it has to redirect back to http://www.example.com/framework/index.php

I would like to redirect every folder and php file back to the index.php, leaving everything else the way it is.

My first problem I encountered was it never redirects to the right folder, always to the domain root folder.

This is what I tried :

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]

This question is related to php .htaccess mod-rewrite

The answer is


You can use something like this:

RewriteEngine on
RewriteRule ^.+$ /index.php [L]

This will redirect every query to the root directory's index.php. Note that it will also redirect queries for files that exist, such as images, javascript files or style sheets.


After doing that don't forget to change your href in, <a href="{the chosen redirected name}"> home</a>

Example:

.htaccess file

RewriteEngine On

RewriteRule ^about/$ /about.php

PHP file:

<a href="about/"> about</a>

To redirect everything that doesnt exist to index.php , you can also use the FallBackResource directive

FallbackResource /index.php

It works same as the ErrorDocument , when you request a non-existent path or file on the server, the directive silently forwords the request to index.php .

If you want to redirect everything (including existant files or folders ) to index.php , you can use something like the following :

RewriteEngine on

RewriteRule ^((?!index\.php).+)$ /index.php [L]

Note the pattern ^((?!index\.php).+)$ matches any uri except index.php we have excluded the destination path to prevent infinite looping error.


I just had to face the same kind of issue with my Laravel 7 project, in Debian 10 shared hosting. I have to add RewriteBase / to my .htaccess within /public/ directory. So the .htaccess looks a like

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [L,QSA]

Silly answer but if you can't figure out why its not redirecting check that the following is enabled for the web folder ..

AllowOverride All

This will enable you to run htaccess which must be running! (there are alternatives but not on will cause problems https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride)


There is one "trick" for this problem that fits all scenarios, a so obvious solution that you will have to try it to believe it actually works... :)

Here it is...

<IfModule mod_rewrite.c>

   RewriteEngine On

   RewriteCond %{REQUEST_FILENAME}  -f [OR]
   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteRule ^(.*)$ index.php [L,QSA]

</IfModule>

Basically, you are asking MOD_REWRITE to forward to index.php the URI request always when a file exists AND always when the requested file doesn't exist!

When investigating the source code of MOD-REWRITE to understand how it works I realized that all its checks always happen after the verification if the referenced file exists or not. Only then the RegEx are processed. Even when your URI points to a folder, Apache will enforce the check for the index files listed in its configuration file.

Based on that simple discovery, turned obvious a simple file validation would be enough for all possible calls, as far as we double-tap the file presence check and route both results to the same end-point, covering 100% of the possibilities.

IMPORTANT: Notice there is no "/" in index.php. By default, MOD_REWRITE will use the folder it is set as "base folder" for the forwarding. The beauty of it is that it doesn't necessarily need to be the "root folder" of the site, allowing this solution work for localhost/ and/or any subfolder you apply it.

Ultimately, some other solutions I tested before (the ones that appeared to be working fine) broke the PHP ability to "require" a file via its relative path, which is a bummer. Be careful.

Some people may say this is an inelegant solution. It may be, actually, but as far as tests, in several scenarios, several servers, several different Apache versions, etc., this solution worked 100% on all cases!


just in case you were still wondering how to redirect all request either if the directory exists (for core framework folders and files) to the framework index handler, after some error/success attempts just noticed I just needed to change the RewriteCond in the .htaccess file

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

the above condition states "not found files" and "not found directories", ok, what if just remove "not found" (!-d) line, and ended with something like the below:

RewriteEngine on
RewriteBase /framework/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /framework/index.php [L,QSA]

It worked for me like a charm


Examples related to php

I am receiving warning in Facebook Application using PHP SDK Pass PDO prepared statement to variables Parse error: syntax error, unexpected [ Preg_match backtrack error Removing "http://" from a string How do I hide the PHP explode delimiter from submitted form results? Problems with installation of Google App Engine SDK for php in OS X Laravel 4 with Sentry 2 add user to a group on Registration php & mysql query not echoing in html with tags? How do I show a message in the foreach loop?

Examples related to .htaccess

Use .htaccess to redirect HTTP to HTTPs Getting a 500 Internal Server Error on Laravel 5+ Ubuntu 14.04 Server unable to read htaccess file, denying access to be safe Laravel 5 – Remove Public from URL Laravel 5 not finding css files How can I fix the 'Missing Cross-Origin Resource Sharing (CORS) Response Header' webfont issue? How Can I Remove “public/index.php” in the URL Generated Laravel? Apache 2.4 - Request exceeded the limit of 10 internal redirects due to probable configuration error Forbidden You don't have permission to access / on this server Htaccess: add/remove trailing slash from URL

Examples related to mod-rewrite

Getting a 500 Internal Server Error on Laravel 5+ Ubuntu 14.04 Forbidden You don't have permission to access / on this server Htaccess: add/remove trailing slash from URL Permission denied: /var/www/abc/.htaccess pcfg_openfile: unable to check htaccess file, ensure it is readable? 404 Not Found The requested URL was not found on this server Redirect all to index.php using htaccess .htaccess not working on localhost with XAMPP URL rewriting with PHP No input file specified htaccess redirect to https://www