Obviously, it's my own opinion, but I've handled config well in my Framework and basically it works like this... The framework has a config folder with any configuration values required by the framework itself (IE: the model needs to know what DB engine, host, etc) but it may not hold any real values (ie the config value may be null, with just the key defined). Next the application has a configuration folder, these are loaded after the frameworks configuration files so the application can overwrite values in the FW config. IE: a specific site uses a database with name XYZ always, so it can go in the application level config - whereby it overwrites the db name from the FW config. Finally, at the root level is a config folder. This folder contains only one file in my repo: .gitignore and it ignores everything but the .gitignore in that folder. This is where private credentials and install specific items go (such as db host for example).
Dero\Core\Config is the class from my FW, and as you can see it loads in order described and merges/overwrites. So lets look at a simple example, basic website configuration:
First is a config in the framework, for example: website.json this is what the FW needs to set up the website in the files I've created. Just some general configuration settings:
{
"image_url": "/images/",
"script_url": "/scripts/",
"style_url": "/styles/",
"site_url": "/",
"template": {
"extensions": ["phtml","php", "tpl", "html"],
"paths": ["dero/view"]
}
}
Then is a config file for the application, for example my website has this website.json which simply defines another view path and the url:
{
"site_url": "http://derokorian.com",
"template": {
"paths": ["app/view"]
}
}
Finally, is in the ignored config - there is never anything in these files that isn't defined in the application config or framework's config. This way when I add a new configuration item - anyone that pulls the update can see the additionally defined fields for use. For example, here is my local website.json which just changes to my local domain:
{
"site_url": "http://local.derokorian.com"
}
This is a rather trivial example, because nothing here is worth protecting. But lets look at my Flickr bar - its a controller for my application that just displays some pictures from the service. For that I have flickr.json from the application config:
{
"api_key": null,
"secret": null,
"favorite_bar": {
"photoset": "72157629096003262",
"userid": "57781201@N05"
}
}
So here we can see api_key and secret are null. I'm simply providing the definition that these must exist but I don't want them checked into any type of version control. photoset and userid are publicly available just by looking on flickr.com so there's no reason they can't be checked in.
So now the problem becomes - how do I get the correct configuration onto a server? Well, I generally SCP from local testing or a testing environment... BUT I have recently started a new project to manage these configurations. its basically just a repo with a cron that installs on a server a long with a folder structure defining configuration for each project per hostname. Its privately hosted repo (on a box in my living room actually) so I'm not worried about it being in a repository. The purpose of the cron is to pull any new configuration I push to the repo. This is just a convenience project, and it allows me to make new hosts easily, by copying a folder from a similar server and making necessary changes. Then I just install the cron and call it a day.