Skip to content
This repository was archived by the owner on Jan 29, 2020. It is now read-only.

Commit 548b138

Browse files
committed
Final edits on modular recipe
- Normalized headers. - Grammatical and phrasing edits. - Added section on caching.
1 parent bb182b1 commit 548b138

File tree

1 file changed

+96
-40
lines changed

1 file changed

+96
-40
lines changed
Lines changed: 96 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,56 @@
1-
How can I make my application modular?
2-
======================================
1+
# How can I make my application modular?
32

4-
ZF2 applications are built with modules - independent units that can provide
5-
configuration, services and hooks to MVC lifecycle.
3+
Zend Framework 2 applications have a concept of modules, independent units that
4+
can provide configuration, services, and hooks into its MVC lifecycle. This
5+
functionality is provided by zend-modulemanager.
66

7-
While ZF ModuleManager can be used with Expressive, we suggest different approach:
8-
modules that are based only on configuration. This is pretty powerful, and (contrary
9-
to ZF modules) doesn't affect performance. It still offers flexibility: each module
10-
can provide its own services (with factories), default configuration and routes.
7+
While zend-modulemanager could be used with Expressive, we suggest another
8+
approach: modules that are based only on configuration. This powerful approach
9+
doesn't affect performance, and offers extensive flexibility: each module can
10+
provide its own services (with factories), default configuration, and routes.
1111

12-
This cookbook will show how to organize modules with
13-
[`mtymek/expressive-config-manager`](https://github.com/mtymek/expressive-config-manager)
14-
- lightweight library that aggregates and merges configuration, optionally caching it.
12+
This cookbook will show how to organize modules using
13+
[mtymek/expressive-config-manager](https://github.com/mtymek/expressive-config-manager),
14+
a lightweight library that aggregates and merges configuration, optionally caching it.
1515

16-
## Install configuration manager
16+
## Install the configuration manager
1717

18-
Configuration manager is available in Packagist:
18+
The configuration manager is available in Packagist:
1919

2020
```bash
2121
$ composer require mtymek/expressive-config-manager
2222
```
2323

2424
## Generate your config
2525

26-
Default Expressive Skeleton comes with `config/config.php` file - main place that
27-
aggregates all configuration. Replace it with following code:
26+
The default Expressive skeleton installs a `config/config.php` file, which
27+
aggregates all configuration. When using the configuration manager, you will
28+
need to replace the contents of that file with the following code:
2829

2930
```php
3031
<?php
3132

3233
use Zend\Expressive\ConfigManager\ConfigManager;
3334
use Zend\Expressive\ConfigManager\PhpFileProvider;
3435

35-
$configManager = new ConfigManager(
36-
[
37-
new PhpFileProvider('config/autoload/{{,*.}global,{,*.}local}.php'),
38-
]
39-
);
36+
$configManager = new ConfigManager([
37+
new PhpFileProvider('config/autoload/{{,*.}global,{,*.}local}.php'),
38+
]);
4039

4140
return new ArrayObject($configManager->getMergedConfig());
4241
```
4342

44-
If you open application in a browser, it should still work in exactly the same way
45-
as it was before. Now you can start adding your modules.
43+
If you open your application in a browser, it should still work in exactly the
44+
same way as it was before. Now you can start adding your modules.
4645

4746
## First module
4847

49-
`ConfigManager` does not force you to use any particular structure for your module.
50-
Only requirement is to expose default configuration using "config provider" - an
51-
invokable class that returns configuration array. For instance, this is how your
52-
module can provide its own routes:
48+
`ConfigManager` does not force you to use any particular structure for your
49+
module; its only requirement is to expose default configuration using a "config
50+
provider", which is simply an invokable class that returns a configuration
51+
array.
52+
53+
For instance, this is how your module could provide its own routes:
5354

5455
```php
5556
namespace App;
@@ -78,24 +79,79 @@ class AppConfig
7879
}
7980
```
8081

81-
## Enabling module
82+
## Enabling the module
8283

83-
Finally, you can enable your module by adding config class `ConfigManager` constructor in
84-
`config/config.php` file:
84+
Finally, you can enable your module by adding a reference to your config class
85+
within the arguments of the `ConfigManager` constructor in the `config/config.php`
86+
file:
8587

8688
```php
87-
$configManager = new ConfigManager(
88-
[
89-
App\AppConfig::class,
90-
new PhpFileProvider('config/autoload/{{,*.}global,{,*.}local}.php'),
91-
]
92-
);
89+
$configManager = new ConfigManager([
90+
App\AppConfig::class,
91+
new PhpFileProvider('config/autoload/{{,*.}global,{,*.}local}.php'),
92+
]);
9393
```
9494

95-
This looks simple, but it is flexible:
96-
- You pass list of config providers to `ConfigManager` constructor.
97-
- Configuration is merged in the same order as it is passed.
98-
- You can override default configuration using `*.global.php` and `*.local.php` files.
95+
## Caching configuration
96+
97+
In order to provide configuration caching, two things must occur:
98+
99+
- First, you must define a `config_cache_enabled` key in your configuration
100+
somewhere.
101+
- Second, you must pass a second argument to the `ConfigManager`, the location
102+
of the cache file to use.
103+
104+
The `config_cache_enabled` key can be defined in any of your configuration
105+
providers, including the autoloaded configuration files. We recommend defining
106+
them in two locations:
107+
108+
- `config/autoload/global.php` should define the value to `true`, as the
109+
production setting.
110+
- `config/autoload/local.php` should also define the setting, and use a value
111+
appropriate to the current environment. In development, for instance, this
112+
would be `false`.
113+
114+
```php
115+
// config/autoload/global.php
116+
117+
return [
118+
'config_cache_enabled' => true,
119+
/* ... */
120+
];
121+
122+
// config/autoload/local.php
123+
124+
return [
125+
'config_cache_enabled' => false, // <- development!
126+
/* ... */
127+
];
128+
```
129+
130+
You would then alter your `config/config.php` file to add the second argument.
131+
The following example builds on the previous, and demonstrates having the
132+
`AppConfig` entry enabled. The configuration will be cached to
133+
`data/config-cache.php` in the application root:
134+
135+
```php
136+
$configManager = new ConfigManager([
137+
App\AppConfig::class,
138+
new PhpFileProvider('config/autoload/{{,*.}global,{,*.}local}.php'),
139+
], 'data/config-cache.php');
140+
```
141+
142+
When the configuration cache path is present, if the `config_cache_enabled` flag
143+
is enabled, then configuration will be read from the cached configuration,
144+
instead of parsing and merging the various configuration sources.
145+
146+
## Final notes
147+
148+
This approach may look simple, but it is flexible and powerful:
149+
150+
- You pass a list of config providers to the `ConfigManager` constructor.
151+
- Configuration is merged in the same order as it is passed, with later entries
152+
having precedence.
153+
- You can override module configuration using `*.global.php` and `*.local.php` files.
99154
- If cached config is found, `ConfigManager` does not iterate over provider list.
100155

101-
For more details, please refer to [Config Manager Documentation](https://github.com/mtymek/expressive-config-manager#expressive-configuration-manager).
156+
For more details, please refer to the
157+
[Config Manager Documentation](https://github.com/mtymek/expressive-config-manager#expressive-configuration-manager).

0 commit comments

Comments
 (0)