Zend Framework 2.0

Add the ability to import config files into other config files

Details

  • Type: Improvement Improvement
  • Status: Open Open
  • Priority: Minor Minor
  • Resolution: Unresolved
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: Zend\Config
  • Labels:
    None

Description

For example:

File: application.ini

[production]

; Regular keys
this.that = "abc"

; Import a config file
import = "/subfolder/routes.ini"

XML version (application.xml)

<?xml version="1.0"?>
<configdata>
    <production>
        <this>
            <that>abc</that>
        </this>
        <import file="/subfolder/routes.xml" />
    </production>
</configdata>
  1. Ini.php
    26/Nov/10 8:21 AM
    12 kB
    Gauthier Delamarre
  2. multiple_ini_file_support.diff
    26/Nov/10 8:21 AM
    2 kB
    Gauthier Delamarre

Activity

Hide
Ben Scholzen added a comment -

For XML, simply use xincludes:

<xi:include href="./some/file.xml"/>

Don't know, if it is supported by the current Zend_Config_Xml implementation, needs to be checked. For INI, it should also be called include, and not import.

Show
Ben Scholzen added a comment - For XML, simply use xincludes:
<xi:include href="./some/file.xml"/>
Don't know, if it is supported by the current Zend_Config_Xml implementation, needs to be checked. For INI, it should also be called include, and not import.
Hide
Marc Bennewitz (private) added a comment -

One addition to INI files:

1. I would use ":include" to make it different to an option named include.
2. xinclude could use on different sections. This should also work on INI files.
Example:

cfg1.ini
include = "option value of include"
:include = "./cfg2.ini"

group.include = "option value of group.include"
group:include = "./cfg2.ini"
cfg2.ini
option = "value"
output as array
array(
    'include' => 'option value of include',
    'option'  => 'value',
    'group'   => array(
        'include' => 'option value of group.include',
        'option'  => 'value',
    )
);
Show
Marc Bennewitz (private) added a comment - One addition to INI files: 1. I would use ":include" to make it different to an option named include. 2. xinclude could use on different sections. This should also work on INI files. Example:
cfg1.ini
include = "option value of include"
:include = "./cfg2.ini"

group.include = "option value of group.include"
group:include = "./cfg2.ini"
cfg2.ini
option = "value"
output as array
array(
    'include' => 'option value of include',
    'option'  => 'value',
    'group'   => array(
        'include' => 'option value of group.include',
        'option'  => 'value',
    )
);
Hide
Rob Allen added a comment - - edited

Having spoken with Matthew, this is something we'd like to see.

I'm not likely to get to it any time soon, so if anyone would like to take this on (and has signed the CLA), please let me know!

Show
Rob Allen added a comment - - edited Having spoken with Matthew, this is something we'd like to see. I'm not likely to get to it any time soon, so if anyone would like to take this on (and has signed the CLA), please let me know!
Hide
Gauthier Delamarre added a comment - - edited

I'm carrying this out.

But before going further, I'd like to dicuss a bit the approach.

I'm not fond of the ':' operator since it's already used by default as inheritance operator. I would suggest something like:

config.ini
[production]
phpSettings.display_errors = false

; inserts the content of subset/common.ini 
; just like if it were typed directly here
@include subset/common.ini

; imports all ini files from the resources.d sub-directory 
; using their name (without extension) as key
resources = @import ressources.d/*.ini

with other files in ressources.d/ looking like this:

resources.d/db.ini
; as it is imported from a "db".ini file, these keys
; will be treated as db.*
adapter = "pdo_mysql"
params.host = "localhost"

this approach aims at mimicking apache2.conf and php.ini ones.

it allows to separate whole parts of the configuration.

What do you think about this?

Show
Gauthier Delamarre added a comment - - edited I'm carrying this out. But before going further, I'd like to dicuss a bit the approach. I'm not fond of the ':' operator since it's already used by default as inheritance operator. I would suggest something like:
config.ini
[production]
phpSettings.display_errors = false

; inserts the content of subset/common.ini 
; just like if it were typed directly here
@include subset/common.ini

; imports all ini files from the resources.d sub-directory 
; using their name (without extension) as key
resources = @import ressources.d/*.ini
with other files in ressources.d/ looking like this:
resources.d/db.ini
; as it is imported from a "db".ini file, these keys
; will be treated as db.*
adapter = "pdo_mysql"
params.host = "localhost"
this approach aims at mimicking apache2.conf and php.ini ones. it allows to separate whole parts of the configuration. What do you think about this?
Hide
Marc Bennewitz (private) added a comment -

To use "@" instead of ":" it's ok for me

Your part to include multiple files by wild-cards is an interesting idea and I have the following questions/issues to this:
1. It will be only supported by ini-files or is there an xinclude port of it?

2. Which wild-cards should be available?
-> Only *, ?
-> Or usage of glob or fnmatch

3. resources = @import ressources.d/*.ini
-> There is no way to create an real option value "@include foobar"
Why not using (Don't tested it yet):
resources@import = ressources.d/*.ini
or resources.@import = ressources.d/*.ini

Additional: Is the a chance to import config files of different types ?
like @include subset/common.xml

Greetings

Show
Marc Bennewitz (private) added a comment - To use "@" instead of ":" it's ok for me Your part to include multiple files by wild-cards is an interesting idea and I have the following questions/issues to this: 1. It will be only supported by ini-files or is there an xinclude port of it? 2. Which wild-cards should be available? -> Only *, ? -> Or usage of glob or fnmatch 3. resources = @import ressources.d/*.ini -> There is no way to create an real option value "@include foobar" Why not using (Don't tested it yet): resources@import = ressources.d/*.ini or resources.@import = ressources.d/*.ini Additional: Is the a chance to import config files of different types ? like @include subset/common.xml Greetings
Hide
Gauthier Delamarre added a comment - - edited

> 1. It will be only supported by ini-files or is there an xinclude port of it?
To be honest I'm not a big fan of XML, and don't it that well - so I would say that if such an implementation exists, well, we can manage to support it

> 2. Which wild-cards should be available?
> -> Only *, ?
> -> Or usage of glob or fnmatch
I feel like glob would do the trick - if I don't use it, I'll be forced to use/emulate regexp, which probably wouldn't be more efficient. So glob is a good candidate for me.

> 3. resources = @import ressources.d/*.ini
> -> There is no way to create an real option value "@include foobar"
> Why not using (Don't tested it yet):
> resources@import = ressources.d/*.ini
> or resources.@import = ressources.d/*.ini
I didn't test neither yet, but I feel like it would be easier and more efficient not to parse the key part of the file. Using key = hard_coded_value / @import/include/something_else would be easier to handle. I wouldn't implement something to complicated if it's not to serve the usability of the component

> Additional: Is the a chance to import config files of different types ?
> like @include subset/common.xml
I guess it would be, but I think this would make harder to implement a caching mechanism, and overall, would be confusing to me

> Greetings
Thanks a lot for your comment and suggestions!

Show
Gauthier Delamarre added a comment - - edited > 1. It will be only supported by ini-files or is there an xinclude port of it? To be honest I'm not a big fan of XML, and don't it that well - so I would say that if such an implementation exists, well, we can manage to support it > 2. Which wild-cards should be available? > -> Only *, ? > -> Or usage of glob or fnmatch I feel like glob would do the trick - if I don't use it, I'll be forced to use/emulate regexp, which probably wouldn't be more efficient. So glob is a good candidate for me. > 3. resources = @import ressources.d/*.ini > -> There is no way to create an real option value "@include foobar" > Why not using (Don't tested it yet): > resources@import = ressources.d/*.ini > or resources.@import = ressources.d/*.ini I didn't test neither yet, but I feel like it would be easier and more efficient not to parse the key part of the file. Using key = hard_coded_value / @import/include/something_else would be easier to handle. I wouldn't implement something to complicated if it's not to serve the usability of the component > Additional: Is the a chance to import config files of different types ? > like @include subset/common.xml I guess it would be, but I think this would make harder to implement a caching mechanism, and overall, would be confusing to me > Greetings Thanks a lot for your comment and suggestions!
Hide
Rob Allen added a comment -

Gauthier,

How far did you get with this?

Rob...

Show
Rob Allen added a comment - Gauthier, How far did you get with this? Rob...
Hide
Gauthier Delamarre added a comment -

hi Rob,

well, I didn't have much time to work on it recently unfortunately...

If needed, I think I can manage to get it out in few weeks from here now.

Gauthier

Show
Gauthier Delamarre added a comment - hi Rob, well, I didn't have much time to work on it recently unfortunately... If needed, I think I can manage to get it out in few weeks from here now. Gauthier
Hide
Rob Allen added a comment -

Gauthier,

It was more a case of if you have code then it would be good to get a prototype and see if we could get it completed for ZF2.

Regards,

Rob...

Show
Rob Allen added a comment - Gauthier, It was more a case of if you have code then it would be good to get a prototype and see if we could get it completed for ZF2. Regards, Rob...
Hide
Gauthier Delamarre added a comment -

well, I've got some good news... I worked a bit on my code today, and I managed to get something working. The bad news are that it's limited to .ini files (or ini formatted files to be more accurate), and does not support Zend_Config_Writer neither.

But his does the trick:

main.ini

[production]
key = "key value"
@include = "conf.d/*.ini"

[development]
devKey = "test"

conf.d/db.ini

[production]
db.adapter = "mysql"
db.param.host = "localhost"

[development]
db.adapter = "dev db adapter"

conf.d/phpSettigns.ini

[production]
phpSettings.display_errors = off

results in this array (generated by ->toArray() on the Zend_Config_Ini("main.ini", "production") object) :

array(3) {
  ["key"] => string(9) "key value"
  ["db"] => array(2) {
    ["adapter"] => string(5) "mysql"
    ["param"] => array(1) {
      ["host"] => string(9) "localhost"
    }
  }
  ["phpSettings"] => array(1) {
    ["display_errors"] => string(0) ""
  }
}

This works with one section or more, and also with no section at all. I tested it many ways, but only manually yet. I still have to write unit tests for it. But has it mostly does... nothing but instantiating new Zend_Config_Ini objects, it shouldn't need that many tests.. Moreover, by having add a "_fileName" property, and thus creating an object for every file, it shouldn't be that difficult to add writing support...

What do you think about it (patch against latest svn version and full class file attached)?

Show
Gauthier Delamarre added a comment - well, I've got some good news... I worked a bit on my code today, and I managed to get something working. The bad news are that it's limited to .ini files (or ini formatted files to be more accurate), and does not support Zend_Config_Writer neither. But his does the trick: main.ini
[production]
key = "key value"
@include = "conf.d/*.ini"

[development]
devKey = "test"
conf.d/db.ini
[production]
db.adapter = "mysql"
db.param.host = "localhost"

[development]
db.adapter = "dev db adapter"
conf.d/phpSettigns.ini
[production]
phpSettings.display_errors = off
results in this array (generated by ->toArray() on the Zend_Config_Ini("main.ini", "production") object) :
array(3) {
  ["key"] => string(9) "key value"
  ["db"] => array(2) {
    ["adapter"] => string(5) "mysql"
    ["param"] => array(1) {
      ["host"] => string(9) "localhost"
    }
  }
  ["phpSettings"] => array(1) {
    ["display_errors"] => string(0) ""
  }
}
This works with one section or more, and also with no section at all. I tested it many ways, but only manually yet. I still have to write unit tests for it. But has it mostly does... nothing but instantiating new Zend_Config_Ini objects, it shouldn't need that many tests.. Moreover, by having add a "_fileName" property, and thus creating an object for every file, it shouldn't be that difficult to add writing support... What do you think about it (patch against latest svn version and full class file attached)?
Hide
Gauthier Delamarre added a comment -

patch against r23445 and full Ini.php files provided

Show
Gauthier Delamarre added a comment - patch against r23445 and full Ini.php files provided
Hide
Laurent declercq added a comment -

I 'm disagreed with the way to process here. The ability to Imports a file is a good feature/idea but it sound like a big improvement and code remaniement. Also, any improvement like this must be ported in all adapters (eg. yaml, xml and so on) to be able to provide a common specification. BTW: I've your looked at the Symfony 2 to take idea for the way to process ?

Show
Laurent declercq added a comment - I 'm disagreed with the way to process here. The ability to Imports a file is a good feature/idea but it sound like a big improvement and code remaniement. Also, any improvement like this must be ported in all adapters (eg. yaml, xml and so on) to be able to provide a common specification. BTW: I've your looked at the Symfony 2 to take idea for the way to process ?
Hide
Evgheni Poleacov added a comment -

In case of your proposal, required to be removed 'config' support from Zend\Application::setOptions() method?

Show
Evgheni Poleacov added a comment - In case of your proposal, required to be removed 'config' support from Zend\Application::setOptions() method?
Hide
Gauthier Delamarre added a comment -

huh it looks like I didn't received update notices regarding this task... is this still expected to be done in ZF2?

Show
Gauthier Delamarre added a comment - huh it looks like I didn't received update notices regarding this task... is this still expected to be done in ZF2?

People

Vote (5)
Watch (8)

Dates

  • Created:
    Updated: