Structuring Yii to run multiple sites from a single framework core
One of the problems you might face is keeping all of your sites that use Yii up-to-date when a new version of the framework core has been released.
What I’m going to suggest is a way use a structure that not only allows you to run multiple sites from the same Yii core, but also keeps multiple versions running so you can choose as and when to upgrade your sites to the latest framework core.
So you have two choices here: You can run on a single core for all your sites (if you like living on the edge) or run multiple versions across many sites so you can maintain stability (with the downside of making a minor change to each sites bootstrap ‘index.php’ file).
If you develop on a local server, or have the luxury of having multiple clients on a single shared server, this structure should help you run fairly smoothly with minimal effort. The process I use is as follows:
- Deploy a new version of the framework core to a single directory.
- Update the config files of the Yii-based sites to use this new version.
- Test said sites against the newest version.
- Promote the new framework core to production server.
- Promote updated config files for Yii-based sites to production server.
This allows me to update each site individually with the knowledge that I don’t immediately need to update all of the Yii-based sites, but also sites that run on older framework cores won’t be affected.
To help explain how this new process works, it helps to understand the directory structure of a newly deployed Yii application (see the official Yii documentation on how to deploy):
/sites/mysite.com/ /sites/mysite.com/index.php /sites/mysite.com/assets/ /sites/mysite.com/css/ /sites/mysite.com/framework/ /sites/mysite.com/images/ /sites/mysite.com/js/ /sites/mysite.com/protected/
What we want to do is split out the ‘/framework/’ directory for shared usage, so here’s a structure that allows multiple cores:
/sites/ /sites/yii/ /sites/yii/1.1.7/framework/ /sites/mysite.com/ /sites/mysite.com/index.php /sites/mysite.com/assets/ /sites/mysite.com/css/ /sites/mysite.com/images/ /sites/mysite.com/js/ /sites/mysite.com/protected/
This structure sets us up for directories dedicated to seperate versions of Yii. You could alternatively have a single Yii directory (‘/sites/yii/’) so you only have one core. But I prefer a multiple version route for various reasons, which I’ll explain later.
The ‘/framework/’ directory is the core of the Yii framework, and deployed every time you create a new web-application using the Yii command line tool. When we deploy a new site in future , the process I use is to delete the ‘/framework/’ directory from the application I’ve just deployed, and point the new application’s bootstrap ‘index.php’ file to that shared framework core.
Once the structure’s been re-arranged, you’ll need to make a code change to ’/sites/mysite.com/index.php’. So, here’s what the standard bootstrap ‘index.php’ file looks like:
<?php // change the following paths if necessary $yii=dirname(__FILE__).'/framework/yii.php'; $config=dirname(__FILE__).'/protected/config/main.php'; // remove the following lines when in production mode defined('YII_DEBUG') or define('YII_DEBUG',true); // specify how many levels of call stack should be shown in each log message defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',3); require_once($yii); Yii::createWebApplication($config)->run();
Simply change the first few lines of code to point to the new core, like so:
<?php // change the following paths if necessary $yii=dirname(__FILE__).'/../yii/1.1.7/framework/yii.php';
Save that and you’re done! The change simply tells PHP to look at a parent path and what version the framework you want to use. The further up the tree structure you put the code, the more double-dot slashes you’ll need. But that setup works fine for me.
If you make that change on all of your web applications, you can run a process of updating your sites fairly quickly. I prefer to run multiple versions like this because I’ve developed quite a few sites with Yii as the core, and like the sanity check of knowing what sites run on what versions (though having said that, I do tend to update all the sites at once, but you might have instances where you can’t). Plus, having multiple versions allows me to rollback should I ever need to.
Another point that I’ve seen about is that some developers also prefer to move their ‘/protected/’ folder out of the web application directory that serves the site. I completely understand why people do this, but with a good, secure host and a solid rewrite config (be it an Apache .htaccess or an IIS web.config), it shouldn’t really be an issue.
What this leads onto next is sharing code you’ve developed across your applications by using this shared core setup, so that you don’t have to keep copying it to each application every time you deploy a new one.
I’ll cover that in the next entry, which will be about (more generally) how Yii’s autoloading works so you don’t really have to think about where your code sits once you’ve written it.
Until then, I hope that’s of some use. And there may be a better way of doing this - so if you know of one or have any other comments, please let me know.