Pages

11 January 2013

Installing Magento in a Subdirectory

I had a situation recently where I wanted to get Magento running under a subdirectory of web root, with Magento requests being seamlessly rewritten from a subdomain to the Magento install, but I didn't want the subdirectory to appear in the URL.

It's easy enough to get Magento running from a subdirectory if you don't mind having that subdirectory appearing in the URL itself directly after the host. You just copy Magento to the subdirectory, access it from http://domain.com/subdirectory and install as normal. This means however that your base URL's then include that subdirectory, and all URLs are generated with it.

If you want to have Magento run from a subdirectory without any indication of this being the case (so no directory in the url), you will find that you come across all kinds of wierd and wonderful solutions from huge, $_POST data disabling .htaccess rewrites (meaning you can no longer save in admin, add any items to the cart etc), to the addition of RewriteBase declarations that cripple any other domains you have running from the web root directory, to moving index.php and .htaccess files to web root and making all kinds of changes to index.php to add in the subdirectory.

Well with a bit of time, and some local development environment debugging, the solution actually boils down to 1 rewrite rule in a web root .htaccess file and one line added to index.php. You don't need to move any Magento files anywhere.

So lets start by installing the store, copy Magento to the subdirectory, and run the installation like normal from http://domain.com/subdirectory or whatever your address might be. Once installation is complete login to admin and I tend to disable and clear cache to stop potential caching issues confusing results. You can do this under System -> Cache Management. Then navigate to System -> Configuration -> Web and remove the subdirectory you will see appended to the Secure and Insecure Base URL's (ensure the Base URL's still finish with a trailing slash). Save the changes (which will break the store, don't worry).

Now create .htaccess if one isn't already there under web root and add the following into it, replace subdomain.domain.com with your subdomain and domain, and magento with your subdirectory:

This is a simple rewrite that just rewrites all requests for the subdomain called subdomain to the magento subdirectory.

NOTE: If you aren't using a subdomain, just alter the HTTP_HOST line to instead be:

RewriteCond %{HTTP_HOST} ^www\.domain\.com$

or:

RewriteCond %{HTTP_HOST} ^domain\.com$

depending on what your web address is.

Next we need to make a change to a $_SERVER variable used to build the request URI by an underlying Zend method before the request is dispatched by the front controller. The class is Zend_Controller_Request_Http, and about halfway down you will see the methods setBaseUrl() and setRequestUri(). Without going into too much unnecessary detail, these methods end up creating an invalid request string by running a substr() of $_SERVER['REQUEST_URI'] and the string length of $_SERVER['SCRIPT_NAME']. When not running from a subdirectory this is fine, as it just ends up stripping off index.php from the REQUEST_URI, but when running from a subdirectory, $_SERVER['SCRIPT_NAME'] reflects the actual script location from web root, so whereas normally it would just contain /index.php, now it contains /magento/index.php. The end result of this is that more than just /index.php gets stripped off the REQUEST_URI, this creates an invalid path, and Magento loads a 404 error page.

All we need to do to correct this is add the following inside <?php ?> tags at the top of index.php within the subdirectory:

$_SERVER['SCRIPT_NAME'] = '/index.php';

And that's it, you should now have a fully functional, seamlessly rewritten Magento store running from a subdirectory.

58 comments:

This was the perfect solution to my problem! Thanks a million! After spending a miserable afternoon trying every RewriteCond/Rule combination imaginable, I didn't realize the problem was in the index.php itself.

hey Hussey, however, i was trying to delete the Magento stuff from the root after i set up the redirection to the sub directory and it comes up with an error about missing files from app folderlooks like the redirection still has dependency on the initial root magento installation

No there won't be any reliance on Magento files in the original website root with the rewrite in place. If you are getting errors about missing files I would say they are either actually missing (perhaps not all moved into the subdirectory?) or it's down to changes to your local fileset. I would do some debugging around the area indicated by the error, you can probably get to the bottom of the problem pretty quickly.

$_SERVER['HTTP_HOST'] actually applies the same for both secure and insecure connections. To determine if a connection is secure or not you need to be looking at variables like $_SERVER['HTTPS'] and $_SERVER['SERVER_PORT'].

Thanks, my issue with SSL turned out to not be related at all to these rewrite rules.The error I was getting with ssl connections was;Error 310 (net::ERR_TOO_MANY_REDIRECTS): There were too many redirects.

The answer was solved by my hosting provider;

The cause here is Magento being confused by our SSL loadbalancer. I've applied this fix which should fix its SSL detection:

All this solution does is a simple forwarding of requests to the subdirectory. If you are having issues with certain urls I would suggest that those problems probably exist without this solution in place.

The solution should work equally well with both domain.com and www.domain.com setups. Make sure whichever one you are using matches the base url defined for the store. You may also want to check your domain configuration to make sure www. is properly catered for.

You don't need to move any of the Magento files outside of the /magento to site root, so index.php should be edited inside the /magento directory. The .htaccess you find inside the /magento directory should not be changed or moved, you just add an extra one as outlined above in the root directory.

This solution does nothing more than simply rewriting all requests to the subdrectory - admin and frontend requests are treated identically. I would suggest you double check the changes and also try it on a clean install as a proof of concept.

It all works great for me - I'm using the www version with magento in a subdirectory.

The only problem I'm getting is when I try the none www version it's reporting as 404 page not found.

Is there another .htaccess command to redirect all none www to the www version? Or have I done something else wrong? I've checked the settings in magento secure and unsecure are both showing the http://www. version

The solution should work identically whatever your stores base url, so if you are getting different results with and without www. I would just double check your setup - something is probably not configured quite right.

You should try the solution on a clean install of Magento as a proof of concept before applying it to an install which has been modified. It is a proven solution so I would suggest that other modifications to your install are causing the issues you are seeing.

Has anyone received "No input file selected" when trying to access the admin after trying this? My front-end works fine from what I've found so far. However, I can't access my admin by just typing http://www.my-domain.cxm/customadmin. It keeps putting /index.php/ before /customadmin/. I can remove /index.php/ out of the URL and then it'll work for one re-direct, then it goes back to "No input file selected." I can keep doing this until I see the dashboard which gives me hope, but that's as far as I can get because /index.php/ is getting generated in all admin links.

I host with SiteGround so none of the "no input... / GoDaddy" fixes applied to me. I tried them anyways, but still nothing worked. However... a very cool support technician there assisted me and saw that I needed some slightly different re-writes due to my hosting account setup on SiteGround.

This original solution at first also caused a huge red flag with SiteGround because I was notified of high resource consumption coming from my account. They shut the website down with 403s because it was so high! Although in the end, again, their support staff was able to assist me even further and figure out that a few additional changes needed to be made to the configuration of our hosting account since we have a dedicated IP address with them, and the caching system that's used there.

Unfortunately while this solution works for many people, there are out-of-the-ordinary cases like ours where it needed a few extra things. Not much though, and I really do appreciate the original solution because now I can finally get rid of the hundreds (literally) of links/pages that search engines keep picking up due to magento generated links/urls. I feel free!!!

For anyone else having issues, I implore you to contact your web hosting provide to see if they are willing to give any insight as to why its not working for you.

If the solution for you is generic enough to be applied to other SiteGround hosted accounts, perhaps you could post it here? I'd be interested to know how it differs for your setup and it could prove useful for others also having issues with the same hosting.

The interesting thing with this is that the second re-write rule by itself (which is the main one mentioned in this blog) worked with no problem on the front-end. It just didn't allow me to get to the back-end. I kept getting the "No input file specified" message. SiteGround added the additional re-write rule displayed with "index.php". I do get "index.php" in my urls in magento admin, but no "magento" at all. This was fine for me.

This is in the mod_rewrite.c section of my .htaccess in /public_html/magento/...

This .htaccess is the standard one from Magento. SiteGround only modified the Rewrite Base line and the "rewrite everything else to index.php" line.

Depending on your setup, you may have to also add the following to your root .htaccess in order to perform mass edits. Its already included in the standard Magento .htaccess thats in my sub-folder, but it wasn't getting executed from that .htaccess some reason.

# Turn the filtering engine On or OffSecFilterEngine Off

And since we have a static IP address and are using their memcache service, they had to do some wizardry on their end in order remove the high resources consumption error/alert that was getting flagged on our account. I have no clue what they did there, but now they have a solved case to look back on if it occurs again! lol

The modification for the ../public_html/magento/index.php file worked fine as specified in this blog.

Thanks for coming back with this detail, it's probably a bit too specific to the hosting to put into the main post, but hopefully it will help someone out should they run into a similar issue with SiteGround.

Can you try the solution on a clean install? The solution is proven to work correctly across a wide range of setups so I would most suspect something specific to your install as being the issue. Also just worth double checking you have done everything correctly.

Thanks. I spent ages reading lots of posts and trying various rewritecond rules before seeing your solution. It should be somewhere obvious on the magento site. Have you tried this with multiple domain websites running off the single magento install?

This is a proven solution, sounds more like you don't have rewrites enabled to me (could be either in Magento or in your virtual host). If the homepage is working correctly that suggests to me requests are getting rewritten correctly to the subdirectory.

Hi Hussey - Thank you for your post. This works perfectly, but is there method to remove index.php from the uri? Not to have it displayed. The way my test site displayed the uri was "MyDomain.com/prodCategory/product-style-a", now it's showing it as "MyDomain.com/index.php/prodCategory/product-style-a". Again is there a way to remove "index.php" from the path?