Installing CakePHP in a Subdirectory

tags: php · cakephp

I've tried installing CakePHP several times on different web hosts, and on each I usually hit a snag when configuring an installation of cake in a subdirectory. There are several reasons for installing in a subdirectory--the primary being that I want to access certain types of resources (like swf and jar files) from the document root, while preserving the cake front controller as the primary director of traffic to the site. The question is, how do I install in a subdirectory without specifing the folder name in the URL, while maintaining access to the current resources on the root of my site?

There are several different areas that I had to address in order to make the installation work correctly.

File Structure

I simply installed a fresh copy of cake in a cake directory on my site's web document root. Additionally, I already had some other resource folders on the document root as well, so my site's folder structure ended up looking something like this:

/www/cake (contains app, cake, docs, and vendors folders)
/www/resources (contains various swf and jar files)

.htaccess

I had to create a slightly modified .htaccess file for the document root of my site, primarily so that I could forward the proper requests to cake, while keeping other requests for my resource files. Using this .htacess also takes care of the issue of the folder name in the URL.

<IfModule mod_rewrite.c>
   RewriteEngine on
   RewriteBase /cake/

   #this rule matches an empty string, and forwards to the app/webroot directory
   RewriteRule    ^$ app/webroot/    [L]


   #this rule does not match requests to actual files, so my resources can be properly resolved
   RewriteCond %{REQUEST_FILENAME} !-f 
   RewriteRule    (.*) app/webroot/$1 [L]
</IfModule>

CakePHP Dispatcher Hack

In Cake Beta: 1.2.0.6311, the only way to get certain requests resolve correctly is to hack the dispatcher.php class (under the cake directory). I noticed that no matter what I did in the core.php configuration file, nothing could prevent the webroot variable (which is used for linking, url routing, etc.) from containing the name of my subdirectory folder. Obviously I didn't want every link in my site to be of the form: http://kushaura.com/cake/controller/etc, so I had to take the drastic action of hacking the dispatcher class.

On line 431 of dispatcher.php, we see the following code:

if (!$baseUrl) 
{
    $base = dirname(env('PHP_SELF'));

if ($webroot === 'webroot' && $webroot === basename($base)) {
    $base =  dirname($base);
}
if ($dir === 'app' && $dir === basename($base)) {
    $base =  dirname($base);
}

if (in_array($base, array(DS, '.'))) {
    $base = '';
}

$this->webroot = $base .'/';
return $base;

This section of code seemed to always return the subdirectory folder name as the $base value (in my case, my subdirectory is called "cake"), so I simply commented this section out, to produce this:

if (!$baseUrl) {
    return '';
}

Finally getting the urls to resolve properly (without the additionally folder name) was a huge relief for me, and this is really a small hack. Unless someone can tell me a better way, I'm fine with doing this for now.

Add A Comment

Some html formatting accepted. Please use Markdown syntax for entering formatting markup. All comments are moderated and we reserve the right to remove inappropriate material.