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:
- When a user navigates to http://www.example.com/index.php they are
getting a 404 error. - When a user navigates to http://www.example.com or
even http://www.example.com/home they wind up on my homepage. - When a user navigates to
http://www.example.com/<anything else>
they either end up on my home page (when using the redirect to/
) or an infinite redirect loop (when using the redirect to/home
).
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:
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.