After a long period of consideration, research, and experiment, we have found a non-static solution for programmatic configuration through a DI container. It is part of a two-stage configuration process, implemented through a ContainerBuilder.

The two stages are “define” and “modify”:

  • In the “define” stage, the Config object defines constructor params, setter method values, and services. This is the equivalent of the previous single-stage Solar and Aura v1 configuration system.

  • The ContainerBuilder then locks the Container so that its definitions cannot be changed, and then begins the “modify” stage. In this second stage, we retrieve service objects from the Container and modify them programmatically.

...

So now, instead of each Aura package carrying a pair of define and modify includes in a subdirectory named for the config mode, we have a single class file for each config mode. The class file is in a subnamespace _Config under the package namespace. Here are two examples, one from the Aura.Web_Kernel package, and one from the Aura.Web_Project package.

Because they are classes, you can call other methods as needed, subclass or inherit, use traits, create instance properties and local variables for configuration logic, and so on. You could even call include in the methods if you wanted, keeping the class as a scaffold for much larger configuration files. This gives great flexibility to the confguration system.

...

To make sure the Aura project installation can find all the package config files, we use the {"extra": {"aura": { ... } } } elements of the composer.json in each package to provide a mapping from the config mode to the config class.

Read the whole article at Composer-Assisted Two-Stage Configuration.

Are you stuck with a legacy PHP application? You should buy my book because it gives you a step-by-step guide to improving you codebase, all while keeping it running the whole time.