Inheritance configs in Zend_Config

For those too lazy to read a long Preface: fast-forward to the last part of "a Simple idea that came to my head."
I wanted to put the anchor, but harperson not allowed :(

the

Zend_Config and sections


Official documentation of Zend Framework is advised to split the configuration file into several sections, each of which is responsible for a different environment in which to work the project.
Thus, one section config can inherit from another, overriding only those settings that should be changed.

At first glance, this idea seems reasonable, but I ran into some limitations of this approach...

Here is an example configuration file from the documentation:
; Production site configuration data
[production]
webhost = www.example.com
database.adapter = pdo_mysql
database.params.host = db.example.com
database.params.username = dbuser
database.params.password = secret
database.params.dbname = dbname

; Staging site configuration data inherits from production and
; overrides values as necessary
[staging : production]
database.params.host = dev.example.com
database.params.username = devuser
database.params.password = devsecret


So, we define a complete list of parameters for the production section, and in sections staging override only a few settings to access the database.

the

Restrictions sectional approach


In practice, first, store the password to a production database in General config is not a good idea, and secondly, the config like this literally impossible to keep the mainstream version control systems (VCS) like Git or Subversion.

Each developer participating in the project, would be committing their own locale in the section of the staging, in the best case — create a custom section otraslevye it from staging.
All this leads to confusion and useless proliferation of configurations in the repository.

the

Traditional scenario of storing config in VCS


The General config is not clogged with personal preferences of the developers, it is usually called as some type of config.default.ini or config.ini.default, put in a repository and then each developer in your working directory makes a copy of it, which calls the config.ini and which adds to the list of files to exclude SLE.

It would seem, here it — happiness: once I've copied the default configuration, drove to your personal settings and forgot about it forever...

As if!

It takes a month and one of the developers decides to add in cofig some useful (or not) setting.
He silently commits this setting in the default configuration, then make changes to the code of a project that completely breaks if the config this setting is not ukazana, and with a sense of accomplishment goes on vacation...

Guess what happens the next day? :)

Even if we consider the utopian situation when the changed config developer did not forget to send a letter to the corporate mailing list with the subject "Please update your local config.ini", and received this letter the developers did not forget to read and, more importantly, to realize and to fulfil — still need to manually update their local config files, sometimes using utilities such as diff, because over time the configs only increase in size and to track all changes manually is not possible.

the

a Simple idea that came to my head


I decided to extend the Zend_Config class and implement the configuration inheritance.
But as soon as I looked at the code I realized that everything needed for inheritance laid down in it originally.

So here's an example of using configuration with inheritance.

General config project — config.common.ini:
[production]
resources.db.adapter = "PDO_MySQL"
resources.db.params.dbname = "system"
resources.db.params.username = "root"
resources.db.params.password = ""
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0

[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1

My personal config config.ini:
[production]
[development : production]
resources.db.params.dbname = "system_laggyluke"
resources.db.params.username = "laggyluke"
resources.db.params.password = "mySecretPassword"


an Example of implementation inheritance configs:
// loaded General configuration
// the third argument to true means that the config is not opened in read-only mode
$config = new Zend_Config_Ini('config.common.ini' 'development' true);
// check whether there is a personal config
if (file_exists('config.ini')) {
// if exists load it...
$configCustom = new Zend_Config_Ini('config.ini' 'development');
// ...and merge two configuration file into one
$config->merge($configCustom);
}
// return config to read-only mode, just in case
$config->setReadOnly();


* This source code was highlighted with Source Code Highlighter.


General config config.common.ini is stored in SLE and any new settings that are added to it, are immediately transferred to all developers. At the same time, each developer can override any setting in your personal config.ini which is ignored SLE.

Of the downsides of this approach can be noted only that in the personal config file you have to list all the sections that were declared in the General config. But for me personally this is not much of a problem, because the list changes very rarely, and often never.

Of course, this idea is not new and I do remember that somewhere this has already met.
I'm just very surprised that such a convenient technique is not described in the official documentation, so may be unknown to many developers.

UPD.
stfalcon suggested that something similar already implemented in Zend_Application, starting with version 1.8.2.
Article based on information from habrahabr.ru

Comments

Popular posts from this blog

Powershell and Cyrillic in the console (updated)

Active/Passive PostgreSQL Cluster, using Pacemaker, Corosync

Automatic deployment ElasticBeanstalk using Bitbucket Pipelines