about me

I'm a 37'ish year old web application developer from South Portland, Maine. I love meeting fellow techies, drop me a line if you want to talk shop.

Categories

Multiple codeigniter sites, using symlinks

Posted on 07/14/2007 at 12:19 PM

I’m posting this here as reference for both myself and anyone else that it might benefit. Its a plan of attack I documented on CodeIgniter’s community forums in order to host multiple sites off a single install base .. its primarily intended to help share code across applications.

Now onto the meat ...

MY REQUIREMENTS

My project called for a specific configuration of sites and applications:

site #1: one application
site #2: has both frontend and backend applications
    
(will also operate on wildcard sub-domains)
site #3: uses ssl with one application
site #4: one application (internal access)

All 4 sites are heavily related ... and will often want to use the same models, libraries, helpers, views etc. Unfortunately CI doesn’t give me a place to store these resources cross-application, and I really didn’t feel comfortable editing or extending the core CI classes. That might have made upgrading the framework painful with later releases. I like the idea of just ‘dropping in’ a new system folder without worry.

MY HOMEWORK (B-)

So as I was looking into CI initially, I found a lot of posts about running multiple-application sites. Overall, I got the impression that this was something CI ‘could’ do with tweaking (depending on your specific sites/applications) but wasn’t particularly great at out of the box. Thankfully, CI is so easy to work with that there are a number of solutions to consider.

Option 1:

One alternative was to run all my apps out of the same application folder, and just give them unique controllers ... I considered this but thought it might be difficult to keep site #1 from calling site #2’s controllers by editing the urls. My sites needed to be fairly secure in this regard.

Option 2:

Another alternative was to modify the loader of the CI core classes to include a new search path, essentially adding a Library level where cross-application code goes. This would have been the most attractive option if I felt more comfortable editing core files. But I don’t ... ick! Hopefully CI adopts a similar solution officially in a later release.

Some related links on that method:

http://www.jaaulde.com/test_bed/CodeIgniter/modLoader/
http://codeigniter.com/forums/viewthread/49157/

And other options I won’t get into right now ...

MY BACKGROUND INFO

My situation is unique to me perhaps. I happen to own the box my sites are being hosted on, so all configuration options are available. My sites use the traditional php5, mysql5, apache2 on Free(as in beer)BSD. I can edit httpd.conf freely and create .htaccess files as needed.

MY SOLUTION

I found I was able to share a (parent) application folder (located outside each site’s root) with a specific site’s (local) application folder ... I did this by creating a series of symbolic links in each (local) application folder to represent the corresponding folders in my (parent) application folder ...

I literally matched symbolic links to parent folders exactly ... EXCEPT for the (local) application’s ‘controllers’ folder, which was really the meat of each website.

It might be easier to show you the following folder hierarchy I used:

application/
    
my global application folderwhere most the code goes
CodeIgniter_1.5.4
/
    
my CI install's system folder and other files, I leave the version 
    number so that I can link to a new system in the index.php if 
    needed for testing
common/
    an apache directory alias called '
common' lets me link to subfolders here
    called img, js, css, file, etc. Having one folder with all my includes makes
    it easy to specify in an .htaccess file that CI should leave links alone with
    the word '
common in it.
Smarty_2.6.18/
    
my smarty installcontains the actual libraries
www_site1
/
    
the site root for site #1
www_site2/
    
the site root for site #2
www_site3/
    
the site root for site #3
www_site4/
    
the site root for site #4

A closer look at my (GLOBAL) application folder:

cache
    SMARTY SPECIFIC FOLDER with write access
config
    standard codeigniter
configs
    SMARTY SPECIFIC FOLDER
controllers
    NOT USED GLOBALLY 
EACH SITE HAS ITS LOCAL CONTROLLERS FOLDER
    FOLDER IS ACTUALLY 
EMPTY
errors
    standard codeigniter
helpers
    standard codeigniter
hooks
    standard codeigniter
libraries
    contains a wrapper 
class called MySmarty.php for smarty useage
models
    standard codeigniter
templates
    SMARTY SPECIFIC FOLDER
templates_c
    SMARTY SPECIFIC FOLDER with write access
views
    standard codeigniter

A closer look at my (LOCAL) application folders (EACH SITE HAS ITS OWN):

cache
    symbolic link to parent
config
    symbolic link to parent
configs
    symbolic link to parent
controllers
    ALL LOCAL SITE SPECIFIC CONTROLLERS GO HERE
    
default controller is index.php as set in CIs global config
errors
    symbolic link to parent
helpers
    symbolic link to parent
hooks
    symbolic link to parent
libraries
    symbolic link to parent
models
    symbolic link to parent
templates
    symbolic link to parent
templates_c
    symbolic link to parent
views
    symbolic link to parent

A closer look at my individual site’s ROOT folders:

.htaccess
    
(see below)
index.php
    links to 
(localapplication folder and global system folder
    system folder can be changed in one place to reference a 
new CI install
applications
    mostly contains symbolic links
but has a legit controllers folder



A closer look at my sites individual .htaccess files:

Options +SymLinksIfOwnerMatch

<IfModule mod_rewrite.c>
    
RewriteEngine on
    RewriteCond 
$!^(index\.php|common|robots\.txt)
    
RewriteRule ^(.*)$ /index.php/$1 [L]
</IfModule>

TWEAKAGE:

A few small edits I made along the way.

For SSL.

Since I have a single CI config file for multiple applications/sites I had to make a small change to the way the $config[base_url] was captured. It now prefixes the URL with the proper protocol if SSL is in use on that site.

$config['base_url']    = (isset($_SERVER['HTTPS']) ? 'https://' 'http://').$_SERVER['HTTP_HOST']."/";

instead of

$config['base_url']    "http://".$_SERVER['HTTP_HOST']."/";

For Smarty.

In my (global) applications autoload.php file, I add the following:

$autoload['libraries'= array('mySmarty');

Then I create a class file in my (global) application/libraries folder (remember to edit the smarty path)

Found on the CI forums, thx to the author whoever you are!

if (!defined('APPPATH')) exit('No direct script access allowed');

require_once(
APPPATH "../../Smarty_2.6.18/libs/Smarty.class.php");

/*
|==========================================================
| Code Igniter - by pMachine
|----------------------------------------------------------
| www.codeignitor.com
|----------------------------------------------------------
| Copyright (c) 2006, pMachine, Inc.
|----------------------------------------------------------
| This library is licensed under an open source agreement:
| www.codeignitor.com/docs/license.html
|----------------------------------------------------------
| File: libraries/Smarty.php
|----------------------------------------------------------
| Purpose: Wrapper for Smarty Templates
|==========================================================
*/

class MySmarty extends Smarty{

    
var $smarty;
    
    function 
MySmarty()
    
{
        $this
->smarty = new Smarty();
        
$this->smarty->template_dir APPPATH "templates";
        
$this->smarty->compile_dir APPPATH "templates_c";
        
$this->smarty->cache_dir APPPATH "cache";
        
$this->smarty->config_dir APPPATH "configs";
        
$this->smarty->compile_check true;
        
$this->smarty->debugging true;
        
log_message('debug'"Smarty Class Initialized");
    
}
    
    
function assign($key,$value)
    
{
        $this
->smarty->assign($key,$value);
    
}
    
    
function display($template)
    
{
        $this
->smarty->display($template);
    
}

}

10 Comments

Comment #1 by E1M2  on  10/24  at  10:51 AM

As noted on CI Forum really like the setup but having some issues.

What does your index.php file look like particularly the $application_folder area? Also are you using one index.php only? Are there any references in your www_* dirs?

Thanks

Comment #2 by E1M2  on  10/24  at  01:17 PM

Solved.

Comment #7
http://codeigniter.com/forums/viewreply/312013/

Comment #3 by Haris  on  02/26  at  08:08 PM

You must be extremely gifted with coding.  Host multiple sites off a single install base sounds like a terrific project. My friend at this mmo community use to host multiple sites but this looks like a great way to do it easily with lots of function.

Comment #4 by CodeOfficer  on  02/26  at  08:50 PM

Thanks Haris. Symlinks are pretty friendly for this sort of thing. Did you find this post by way of a CodeIgniter project?

Comment #5 by terenuri intravilane  on  03/20  at  12:18 PM

Hi,
I use smarty too for template and I like to learn how people are with it and dealing with situations that is covered by standard CI but probably have to handle separately when using with Smarty.

Comment #6 by ontwikkeling  on  04/16  at  03:25 AM

I’ve never used a PHP framework before, and it amazes me! I guess I make my framework up as I go along on my websites, but this thing is so amazing. I’m very impressed.

Comment #7 by Michael  on  05/03  at  12:55 AM

Here’s a shell script for making creation easier (not running a mac, and my server isn’t running a window manager):

#!/bin/sh
mkdir ~/www/$1

ln -s ~/www/application/cache ~/www/$1/cache
ln -s ~/www/application/config ~/www/$1/config
ln -s ~/www/application/errors ~/www/$1/errors
ln -s ~/www/application/hooks ~/www/$1/hooks
ln -s ~/www/application/libraries ~/www/$1/libraries
ln -s ~/www/application/models ~/www/$1/models
ln -s ~/www/application/views ~/www/$1/views

# create our controller
mkdir ~/www/$1/controllers
touch ~/www/$1/controllers/index.php

Saved me some time.

Comment #8 by CodeOfficer  on  05/03  at  01:34 AM

Thanks Michael, good stuff! I did something similar when I did this, I’ll have to look for the script.

Comment #9 by application development  on  05/27  at  08:15 AM

I use smarty too for template and I like to learn how people are with it and dealing with situations that is covered by standard CI but probably have to handle separately when using with Smarty.
An example is form.

Comment #10 by Greg  on  08/11  at  09:22 AM

Hi CodeOfficer ... very interesting post. Thanks for sharing it!

I have a similar situation, although my solution is a bit different (as are my project needs) ... so I’m wondering what your thoughts are regarding a post I just made at the CI forums - http://codeigniter.com/forums/viewthread/125954/

Leave a comment?

Please use Pastie or Gist if you need to write code in your comments.

Name:

Email:

Location:

URL:

Remember my personal information

Notify me of follow-up comments?

Please enter the word you see in the image below:


RailsConf 2008 Often times I will release code for free or go that extra distance to help others online. If my skills were useful to you, please consider a small donation. Thank you very much.

recommend me!

Search

You Can Find Me

@ github.com
@ twitter.com
@ calendaraboutnothing

My Wishlists

@ Amazon.com

My Other Sites

Foundation's Edge, RJones Family, We're Not.com (only for staging), Ailee Jones (same as rjones for now)

Friends of Mine

Aaron, Barnaby, Brian, Chris, Dirk, Frank, Four, Justin, Matt, Mike, Monty, Paul, Sean, Travis

IRC Hangouts

I can usually be found lounging on irc.freenode.net while I work, on the following channels: #fauna, #github, #hello-heroku, #jquery, #passenger, #ruby, #rubyonrails, #slicehost, #sproutcore, #textmate, #werenot.