Storing the settings into database
CakePHP, Development, Frameworks, General October 19th, 2007
Today I would like to show you how I am storing and fetching the settings for my applications in CakePHP. The reason why I am doing this is pretty obvious - once the application is complete and installed it’s better to have settings such as
- How many rows per page to show in the paginated table
- Where is the upload dir for the files
- What is the Date format used in the application
And many other.
Ok, without other words here is the code explanation:
The Database table is very simple:
`id` int(11) NOT NULL AUTO_INCREMENT,
`key` varchar(255) NOT NULL,
`pair` text NOT NULL,
`description` text NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
PRIMARY KEY (`id`)
)
Key column will store the name of the setting /I am using only capital words with underscore (_) for the replacement of the spaces.
Pair is the settings value.
Description will store the human readable description of the setting as well as some explanation of the possible values.
The other 3 fields are pretty simple - ID is the primary key of the table, created and modified are the system columns where cakePHP stores the creation and last modification date.
Pair is text because this field also can store large texts like some disclaimer or some footer notes. Otherwise it should be simple varchar, but because we wont make heavy searched in that column it’s not critical
So, I wont stop to the UI for the settings interface. Mine was created with /console/cake script and it’s quite simple:
Add - you can fill all fields in the form,
Edit - you can change only the pair /the value/ and the description,
View - preview of the single row,
Index - showing the table with Description and pair just to indicate what we have in the settings table.
Delete - action is removed - and you know why better than me :), we don’t want some “smart” guy to decide that something is not important and to wipe it out and after this YOU are guilty and you have to search and check which setting is missing and to enter it again.
Ok, let’s imagine that we have all the UI set up and working, so how to load these things into the application so every script can see them?
Let’s create small function in the AppController class which will do the job /if you don’t have that file in you app directory, just copy it from /cake/:
class AppController extends Controller {
...
/* Function which read settings from DB and populate them in constants */
function fetchSettings(){
//Loading model on the fly
App::import(’Model’, ‘Setting’);
$settings = new Setting();
//Fetching All params
$settings_array = $setting->findAll();
foreach($settings_array as $key=>$value){
$constant = "__".$value['Setting']['key'];
$val = $value['Setting']['pair'];
if(!defined($constant)){
eval("define(\$constant, \$val);");
}
}
}
...
}
?>
What is the role of this function?
First - load the Settings model on the fly /we want to make sure that the model is loaded when we call it no matter on which Controller/. Then fetching all Settings rows in $settings_array.
After this in the loop we define all key values as name of the constant and we assign to all of them the pair value.
Because it’s not possible to define them all with deinfe($key, $value) - it’s not possible with PHP. I am creating a scring which after this I evaluate as PHP code.
That’s it, you have all your settings as constants they will look like:
Update:
As rightly pointed, the trend in the next release of CakePHP is to move all constants in core.php to be loaded and modified with Configure class. Here is the modification which will meet this code standart:
class AppController extends Controller {
...
/* Function which read settings from DB and populate them in constants */
function fetchSettings(){
//Loading model on the fly
loadModel('Setting');
$settings = new Setting();
//Fetching All params
$settings_array = $setting->findAll();
foreach($settings_array as $key=>$value){
Configure::write("__".$value['Setting']['key'], $val);
}
}
...
}
?>
So what is the change - I am setting all variables with Configure::write() function in the configurations and after this if I need to use one of them I just need to call:
End Update
Note the double underscore in front of each constant. They are attached in that function, I put them to make the constant unique in Cake world - so far there are only functions starting with double underscore.
Now you have just to add this function in your beforeFilter() callbacks on each controller and that’s it
I am joking, you need to add this just in one place in the AppController class so here is the code:
class AppController extends Controller {
...
function beforeFilter(){
$this->fetchSettings();
...
}
...
function fetchSettings(){
...
}
}
?>
That’s it! Now everywhere, in controllers and helpers /all user interface logic/ you have these constants, so you can use them easily.
I will be glad to hear our opinion for this.
Add to:


Why don’t you write the values in the Configure object instead of defining constants?
Nice overview, but like Daniel said, would be better to use the Configure::write() / read() and avoid constants.
Another thing also, isn’t it better to make a component for the settings and instead of a findAll(), use some conditions and specific fields to return?
Thank you, for your comments guys.
@Daniel, I am frequent reader of your blog and I read about this from your article about “Deprecation warnings…”. It’s nice approach.
So far it’s still not in the official release /at least the settings in core are constants.
Anyway, this is a nice hint and I will modify the code of the example.
Update:
About the suggestion for Component - I think the question is reasonable, but so far I didn’t use many settings /but it’s nice tohave in the future/. About limitations: if we have limitations then it’s better to use them directly from the database, but this is not the aim I think especially when I have only 10-15 rows in that table.
Thanks again.
There is actually a component for this, the ConfComponent by Othman, however I found I could only get the variables to work in views. I’ve taken it out and I’m using your technique just now, although I might end going down the Configure::write option.
You can check out the code in action on http://dev.pastemonkey.org, as I’ve not migrated it into the live version yet.
@Tane - thanks for your comment.
I didn’t know about the component by Othman, but I think this one it quite simple to be used as component /if we need to be quite strict - yes but it’s 10 lines of code :)/
About pastemonkey - very neat design. Hope it become popular in the future
@Nik
Thanks.
I’ve been playing about with things and I decided to go down the Configure::write option instead. I’ve been cutting a lot of chaff of the app today, and now have it down to six simple tables
It’ll only become popular if people know about it, so please help spread the word
I do this, but I also cache the settings….
Not sure why, grabbing a few settings is trivial, but I guess I am a cache whore! xD
[...] CakePHP - Storing the settings into database [...]
Great article. I was just lookin for such solution. One thing - loadModel is deprecated, you should use App::import(’Model’, ‘Setting’) instead.
@snowdog - glad that helps
About loadModel - I know, but the article was written before the function has been depricated, but it’s nice to be updated anyway. Thanks for the buzz.
You have omitted $val = $value['Setting']['pair']; in your brand new fetchSettings method