⬆️ ⬇️

Inheritance of configs in Zend_Config

For those who are too lazy to read the long preface: rewind to the last part “A simple idea that came to my mind”.

I wanted to put the anchor, but habraparser does not allow: (



Zend_Config and sections



The official documentation of the Zend Framework advises to split the configuration file into several sections, each of which will be responsible for the different environment in which the project should work.

At the same time, one section of the config can inherit another, overriding only those parameters that need to be changed.



At first glance, this idea seems reasonable, but I was faced with 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 in the production section, and in the staging section we redefine just a few parameters for access to the database.



Limitations of the sectional approach



In practice, firstly, storing the access password to a database in a common config is not a good idea, and secondly, a config in this form cannot literally be stored in mainstream version control systems (SCR) such as Git or Subversion.



Each developer participating in the project will be happy to commit their own local settings to the staging section, at best, create their own section, following it from staging.

All this leads to confusion and useless growth of the config in the repository.



Traditional storage configuration scripts in hard currency



To prevent the common config from being clogged by the personal settings of developers, it is usually called something like config.default.ini or config.ini.default, put into the repository, and then each developer in its working directory makes a copy of it, which is called config.ini and which adds to the list of ignored hard currency files.



It would seem, here it is - happiness: once copied the default config, drove in there personal settings and forgot about it forever ...



No matter how wrong!



A month passes and one of the developers decides to add some useful (or not) customization to the cofig.

He silently commits this setting to the default config, then makes changes to the project code, which is completely broken if this setting is not specified in the config, and with a sense of accomplishment, goes on leave ...



Guess what happens the next day? :)



Even if we consider the most utopian situation, when the developer who changed the config does not forget to send a letter to the corporate newsletter with the subject "Please update your local config.ini", the developers who received this letter do not forget to read it and, importantly, realize and execute it - anyway they all have to manually update their local configs, sometimes using diff-type utilities, because over time configs only grow in size and it is not possible to track all changes manually.



Simple idea that came to my mind



I decided to extend the Zend_Config class and implement the inheritance of configs in it.

But as soon as I looked into its code, I immediately understood that everything necessary for inheritance was incorporated into it initially.



So, here is an example of using configs with inheritance.



The general configuration of the 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 the implementation of confidentiality inheritance :

//

// true , read-only

$config = new Zend_Config_Ini( 'config.common.ini' , 'development' , true );

// ,

if (file_exists( 'config.ini' )) {

// - ...

$configCustom = new Zend_Config_Ini( 'config.ini' , 'development' );

// ...

$config->merge($configCustom);

}

// read-only,

$config->setReadOnly();




* This source code was highlighted with Source Code Highlighter .




The general config.common.ini config is stored in hard currency and any new settings that are added to it immediately go to all developers. At the same time, each developer can override any setting in his personal config.ini, which is ignored by SLE.



From the minuses of this approach, I can only note that in the personal config it is necessary to list all the sections that were declared in the general config. But for me personally, this does not constitute a special problem, because their list changes extremely rarely, and more often never.



Of course, this idea is not new, and I remember exactly that I have already met such an approach somewhere.

I just was very surprised that such a convenient method is not described in the official documentation, which means it may not be known to many developers.



UPD.

stfalcon suggested that something similar has already been implemented in Zend_Application, starting with version 1.8.2.

Source: https://habr.com/ru/post/61090/



All Articles