Change the config at run time

18 September, 2006

Show comments

Following on from my previous post, I thought I'd mention a similar use that can make a developers life a little easier. Usually when developing software there are at least 3 environments: Development, Test and Production. For larger projects there may be more, but for a simple website (and a tiny team of 1) there is often 2 environments: the one on the development machine and the live site.

So picture the scene, you just finished adding some enhancements to your website, all goes remarkably well on your local machine, and after running through your last few tests you decide you are ready for the move to your production server. So, you export the database, initiate the file transfer and then go to your live site and.... disaster: You have a completely blank screen that you desperately want to get rid of. What do you do? The error doesn't occur on your local machine so you have to debug in the production environment - better do it quick before a user notices and phones the helpline... But there is a better way.

A production environment should never have a debug setting other than 0, which means that php errors are hidden, and Cake error messages are none-descriptive 404s. That's definitely the way it should be, so how to debug without letting the world see?

Set up a separate environment

The easiest way to set up a different environment, is to create a subdomiain, that refers to the same app folder. It would be wise to put some extra security on this testing environment, that is intended to be for your eyes only ;). "But" I hear you cry "then it'll be exactly the same as the main application" - that-s right, and that's what you need with one minor difference.

Modify your configuration on the fly

Config element used to change settings at run timeWhat is needed is quite simply two things

  • The possibility to set a variable for later use
  • The possibility to use said variable to set the config constants

It probably doesn't need much explanation given the image to the right, and it may not be considered that good an idea so I'll stress that this is for a testing/development environment only.

Setting up the config files

So with a glance at the above image, it should be clear where I'm going. With a minor change to your /app/config/core.php file it is possible to modify you DEBUG constant if and only if you are in your development/test environment and there is a session variable set to override the default value:

Likewise a similar change to your /app/config/database.php file means that from your development/test environment you can dynamically switch database sources - this should be done with caution, if your production data isn't to be fiddled with it would be better to provide read-only access by restricting the appropriate database user:

A means to make that change

With the above changes in place if you test you should find that... absolutely nothing changes. That's the desired result, as until now there has been no override set and as such the default values are taken which is what should be desired. So how do you change a value? Well all you need to do is have a means, any means, of setting a session variable, so how about this:

Now all that's needed is a means of calling the controller with a form, so with a config element like this:

... All the tools necessary to change debug and database settings are available at your finger tips.

Summing up

With the code shown here, it should be possible to ensure that the appropriate constants and settings are set to speed up ad-hoc testing and debugging. Referring back to the original scenario, the developer could easily enter the debugging environment (which should be protected from public access) to find out what error has occurred that is not visible in the development environment - all without the possibility of a member of the public seeing potentially sensitive info on the screen and without taking the site completely offline to do so.

I hope that you found this useful, or at least it sparked an "O yeah, I could do..." type thought ;)