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:
RewriteEngine On RewriteCond %{HTTP_HOST} ^subdomain\.domain\.com$ RewriteCond %{REQUEST_URI} !^/magento/ RewriteRule ^(.*)$ /magento/$1This 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.