Let me tell you a little story.  My latest site I have been working on for some time was written using the Zend Framework.  Since it was launched in Oct 07, it has been growing rapidly enough where I am now starting to feel growing pains.

One morning I went into the site to check some analytics, and my site was displaying a 403 Forbidden error!  I suddenly got a cold nervous sweat down the back of my spine.  Why was it forbidden?  It was fine when I checked it out last night?!  So I tried to login to my FTP account.  No go!  I I thought a hacker has some how blocked me out of my own account. [Exit dramatic build up].

I come to find out that my hosting company revoked my access to the folder that I was using for the domain.  I called them up immediately after I noticed that.  They responded by telling me that on a shared server, they limit their clients to use only 2% of the servers resources before they shut them down.  My site was using 30%. They were then forced to shut the site down without notice, because it was most likely affecting the performance of the other sites running from that shared server.

After some negotiating and explaining to them that I was going to come up with a solution, they temporarily gave me back access to the folder so that I could diagnose further what was going on.  The first thing that I did was looked through the server logs.  Because of my unfortunate neglect, the server log file was freaking enormous bigger than normal.

Nearly all of the errors I was getting were:

[03-Jul-2008 09:41:19] PHP Fatal error:  Uncaught exception 'Zend_Db_Adapter_Exception' with message 'SQLSTATE[42000] [1203] User blank already has more than 'max_user_connections' active connections' in blah blah blah

I’ll admit, I was in a huge hurry to get this project done, so I wasn’t thinking about the long tern effects.  Needless to say, I wasn’t caching my MySQL query results. I know, tisk tisk. Once I discovered this, I added this private method to my classes:


private function loadCache()
{
$frontendOptions = array(
'lifetime' => 7200, // cache lifetime of 2 hours
'automatic_serialization' =>
true);
$backendOptions = array(
'cache_dir' => './cache/' // Directory where to put the cache files
); // getting a Zend_Cache_Core object
return Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);
}

Then in each of my classes where I needed to cache my query results, I implemented the above method. Here is an example:


class IndexController extends Zend_Controller_Action {
/**
* Index Action
*
*/
public function indexAction() {
$db = new SomeDB;
$cache = $this->loadCache();
if (!$results = $cache->load('cache_variable')) {
$results = $db->fetchAll('columnName="whatIWant"');
$cache->save($results, 'cache_variable');
}
}
}

It’s pretty much as simple as that.  Once I did this, it dropped the server load tremendously, which now buys me more time from upgrading my hosting package.  About 10 minutes of coding just saved me about $50 a month in hosting fees!  That feels good.

Keep in mind that this is not the best approach to solving this problem.  If you too are using the Zend Framework in your own design.  It was be better to initialize the Zend_Cache in your bootstrap file.  Doing it the way I did above will force you to replicate the code method, loadCache, in all of your classes which I dont’ have to explain to you why this is inefficient, and just plain old bad OOP technique! :P