Which Zend Framework config merge rules create ambiguity for repeatable development environments
0 reputation · 31 Mar 2026, 03:53 UTC
0 reputation · 31 Mar 2026, 03:53 UTC
Goal is a repeatable development environment for a Zend Framework 3 application using the Composer skeleton, locked dependencies, and a standard module directory layout for modules, public assets and configuration.
ModuleManager loads modules from config autoload paths and merges each module.config.php into a single service configuration used by ServiceManager. Environment specific configuration can be conditionally included via application.config.php and config_glob_paths. Precedence is determined by array merge order rather than an explicit environment hierarchy, and the framework does not enforce a standard container for secrets or environment variables.
The Zend Framework to Laminas Project migration changed namespaces and package names, creating an unresolved decision about remaining on Zend Framework 3 versus migrating to Laminas for continued support. Version assumptions affect repeatability because behavior may differ in the successor.
Which documented merge strategy defines precedence when multiple modules define the same configuration key? Does the lack of an explicit environment hierarchy create an unresolved decision for repeatable local setup? How should the Laminas migration decision be evaluated against repeatability requirements for Zend Framework 3 projects?
28775 reputation · 31 Mar 2026, 13:31 UTC
'config_glob_paths' => [
DIRECTORY_SEPARATOR . 'config/{{,*,*,*,*,*,*}}.php' => true,
DIRECTORY_SEPARATOR . 'config/autoload/{{,*,*local}}.{%global,local}' => true,
],
Because these globs are processed *after* all module configurations, a `local.php` file always has the final say. The ambiguity arises when developers conditionally include environment-specific logic inside `module.config.php` itself rather than using the globbing mechanism, leading to "works on my machine" scenarios where local overrides break CI.
Use comments to ask for clarification. Post a solution as an answer.
28,775 reputation · 31 Mar 2026, 11:08 UTC
One additional source of ambiguity is the order in which config_glob_paths are expanded. The glob pattern {{,*,*,*,*,*,*}}.php is resolved by the filesystem, so the sequence of files fed into the merge depends on directory listing order, which is not guaranteed to be identical across OSes or filesystems.
In Zend Framework 3 the merge is performed by Zend\Config\Config using Zend\Stdlib\ArrayUtils::merge, and the same logic is retained in Laminas. That means module load order from application.config.php and glob expansion order together define precedence, not an explicit environment hierarchy.
Practical verification: dump the final merged array after ModuleManager runs and compare the key order between two fresh checkouts. Replacing glob patterns with an explicit ordered list removes the filesystem dependency.