Apache Redirect to /index.php – How to handle direct requests for /index.php

301-redirectApache2mod-rewriterewritecond

I'm not 100% sure if this should be on server fault or stack overflow, though I'm leaning towards server fault.

Most PHP frameworks utilize Apache redirects to funnel all request to /index.php and then the framework handles the routing from there. The issue I'm having is that our old site did not use this methodology and /index.php really was our home page. Now that we released a new site, we want to redirect all direct requests to /index.php to /home.

I feel like I remember there being a switch or something in Apache which only performs a redirect if the current request is not the result of another 301 redirect. I can't seem to find anything like this though. Am I making this up? If I am, is there some way to handle this situation?

I've stripped out my Apache configuration file to the absolute bare minimum to eliminate the chance of unknown redirects. Here it is (though the domain name has been redacted):

##
# Some LoadModule includes
##

## Set the IP and ports for this server
Listen 10.0.15.246:80

## zend fastcgi
AddType application/x-httpd-php .php
AddHandler fastcgi-script .php

<VirtualHost *:80>

    ## Set various vhost values
    ServerName www.example.com
    DocumentRoot /www/www.example.com/htdocs/public
    DirectoryIndex index.php

    ##Set development environment
    SetEnv WEB_ROOT /www/www.example.com/htdocs/public
    SetEnv APPLICATION_ENV development

    RewriteEngine On

    ## My attempts to redirect /index.php to either / or /home
    #RewriteRule /index.php$ /home [R=301,NC,L]
    #RewriteRule /index.php$ / [R=301,NC,L]

    <Directory /www/www.example.com/htdocs/public>
        DirectoryIndex index.php
        AllowOverride All
        Order allow,deny
        Allow from all

    </Directory>

</VirtualHost>

I have an .htaccess file located at /htdocs/.htaccess which is completely blank.
I also have an .htaccess file located at /htdocs/public/.htaccess which contains the following and nothing else:

RewriteEngine On
# The following rule tells Apache that if the requested filename
# exists, simply serve it.
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
# The following rewrites all other queries to index.php. The
# condition ensures that if you are using Apache aliases to do
# mass virtual hosting, the base path will be prepended to
# allow proper resolution of the index.php file; it will work
# in non-aliased environments as well, providing a safe, one-size
# fits all solution.
RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L]

What is currently happening:

What I want to change is:

  • When a user goes to http://example.com/index.php they end up on my homepage.

  • When a user navigates to http://www.example.com/<anything else> it goes to the appropriate page (or a 404 error if it doesn't exist).

Best Answer

I couldn't find a flag/switch in Apache which prevented a redirect on an existing request which was previously redirected.

Instead, I looked to implementing a solution within the application itself.

For example, since my application was a Zend Framework 2 application, my solution was adding this to the /htdocs/public/index.php file:

if(trim($_SERVER['REQUEST_URI']) === '/index.php'){
    header("Location: /home",TRUE,301);
    die();
}

It's not the cleanest of solutions. But I only include the pieces of ZF2 I need rather than the whole package, so I don't have to worry about the file being overwritten due to an update.

Related Topic