Skip to content

Commit 9dfa13f

Browse files
committed
Enhance documentation for FastForward Config
- Updated providers documentation to clarify provider-based configuration and usage examples. - Added detailed sections on exceptions, helpers, and traits to improve understanding of the package's capabilities. - Expanded API reference with clear descriptions of interfaces and classes, including their responsibilities and use cases. - Improved installation instructions with requirements and package details. - Enhanced quick start guide with practical examples for loading configurations from various sources. - Introduced a new section on compatibility, outlining supported capabilities and practical notes. - Added a FAQ section addressing common questions and clarifying usage scenarios. - Created a new page for common use cases to provide realistic examples of configuration patterns. - Improved directory structure documentation to clarify loading and organizing configuration files. - Added links for coverage reports and dependencies for better resource navigation. Signed-off-by: Felipe Sayão Lobato Abreu <github@mentordosnerds.com>
1 parent 993549f commit 9dfa13f

25 files changed

Lines changed: 1059 additions & 214 deletions

README.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
## ✨ Features
88

9-
- 🔑 Dot notation access: `config->get('app.env')`
9+
- 🔑 Dot notation access: `$config->get('app.env')`
1010
- 📁 Load from arrays, directories, or providers
1111
- ♻️ Lazy-loading with `__invoke()`
1212
- 🧩 Aggregation of multiple sources
@@ -29,8 +29,7 @@ composer require fast-forward/config
2929
### Load configuration from multiple sources:
3030

3131
```php
32-
use FastForward\Config\{config, configDir, configCache};
33-
use Symfony\Component\Cache\Simple\FilesystemCache;
32+
use function FastForward\Config\config;
3433

3534
$config = config(
3635
['app' => ['env' => 'production']],
@@ -46,12 +45,10 @@ echo $config->get('app.env'); // "production"
4645
### Cache configuration using PSR-16:
4746

4847
```php
49-
$cache = new FilesystemCache();
48+
use function FastForward\Config\configCache;
5049

51-
$config = configCache(
52-
cache: $cache,
53-
['foo' => 'bar']
54-
);
50+
/** @var \Psr\SimpleCache\CacheInterface $cache */
51+
$config = configCache($cache, ['foo' => 'bar']);
5552

5653
echo $config->get('foo'); // "bar"
5754
```
@@ -61,6 +58,8 @@ echo $config->get('foo'); // "bar"
6158
### Load from a recursive directory:
6259

6360
```php
61+
use function FastForward\Config\configDir;
62+
6463
$config = configDir(__DIR__ . '/config', recursive: true);
6564
```
6665

@@ -69,6 +68,8 @@ $config = configDir(__DIR__ . '/config', recursive: true);
6968
### Use Laminas-style providers:
7069

7170
```php
71+
use function FastForward\Config\configProvider;
72+
7273
$config = configProvider([
7374
new Vendor\Package\Provider1(),
7475
new Vendor\Package\Provider2(),
@@ -106,8 +107,8 @@ config/
106107

107108
- `config(...$configs): ConfigInterface`
108109
- `configCache(CacheInterface $cache, ...$configs): ConfigInterface`
109-
- `configDir(string $dir, bool $recursive = false, ?string $cache = null): ConfigInterface`
110-
- `configProvider(iterable $providers, ?string $cache = null): ConfigInterface`
110+
- `configDir(string $rootDirectory, bool $recursive = false, ?string $cachedConfigFile = null): ConfigInterface`
111+
- `configProvider(iterable $providers, ?string $cachedConfigFile = null): ConfigInterface`
111112

112113
---
113114

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@
4343
"ergebnis/composer-normalize": true,
4444
"fast-forward/dev-tools": true,
4545
"phpdocumentor/shim": true,
46-
"phpro/grumphp": true
46+
"phpro/grumphp": true,
47+
"pyrech/composer-changelogs": true
4748
},
4849
"platform": {
4950
"php": "8.3.0"

docs/advanced/caching.rst

Lines changed: 66 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,77 @@
11
Caching
22
=======
33

4-
FastForward Config supports PSR-16 caching for configuration data. This allows you to cache the merged configuration, improving performance for large or complex setups.
4+
FastForward Config supports two different caching approaches. They solve related problems, but they are not the same feature.
55

6-
How it works
7-
------------
8-
- Wrap your config with ``configCache($cache, ...)``.
9-
- The first access will store the merged config in the cache.
10-
- Subsequent accesses will read from cache, unless you clear it.
11-
- Any PSR-16 compatible cache (e.g., Symfony, Doctrine, etc) is supported.
6+
.. list-table:: Cache options
7+
:header-rows: 1
128

13-
Example
14-
-------
9+
* - Option
10+
- Best for
11+
- Storage
12+
* - ``configCache()`` or ``CachedConfig``
13+
- Caching the final merged config behind any PSR-16 backend.
14+
- Your cache implementation.
15+
* - ``cachedConfigFile`` on ``configDir()`` or ``configProvider()``
16+
- Reusing a generated PHP cache file for directory or provider aggregation.
17+
- A file on disk handled by Laminas ConfigAggregator.
18+
19+
Caching With PSR-16
20+
-------------------
21+
22+
Use ``configCache()`` when your application already has a PSR-16 cache backend:
23+
24+
.. code-block:: php
25+
26+
use Psr\SimpleCache\CacheInterface;
27+
use function FastForward\Config\configCache;
28+
29+
/** @var CacheInterface $cache */
30+
$config = configCache($cache, __DIR__ . '/config');
31+
32+
On the first resolution, the merged configuration is stored in the cache. Later resolutions read from the same cache key.
33+
34+
Using A Custom Cache Key Or Persistent Writes
35+
---------------------------------------------
36+
37+
Instantiate ``CachedConfig`` directly when you need more control:
38+
39+
.. code-block:: php
40+
41+
use FastForward\Config\CachedConfig;
42+
use Psr\SimpleCache\CacheInterface;
43+
use function FastForward\Config\configDir;
44+
45+
/** @var CacheInterface $cache */
46+
$config = new CachedConfig(
47+
cache: $cache,
48+
defaultConfig: configDir(__DIR__ . '/config', recursive: true),
49+
persistent: true,
50+
cacheKey: 'app-config',
51+
);
52+
53+
.. warning::
54+
55+
``configCache()`` creates ``CachedConfig`` with the default ``persistent: false`` behavior. That means ``set()`` and ``remove()`` update the resolved in-memory config, but they do not write the modified result back to the cache backend unless you instantiate ``CachedConfig`` yourself with ``persistent: true``.
56+
57+
Caching Provider Or Directory Aggregation To A File
58+
---------------------------------------------------
59+
60+
If you want Laminas ConfigAggregator to write a cache file, use ``cachedConfigFile``:
1561

1662
.. code-block:: php
1763
18-
use Symfony\Component\Cache\Simple\FilesystemCache;
64+
use function FastForward\Config\configDir;
1965
20-
$cache = new FilesystemCache();
21-
$config = configCache($cache, ['foo' => 'bar']);
66+
$config = configDir(
67+
__DIR__ . '/config',
68+
recursive: true,
69+
cachedConfigFile: __DIR__ . '/../var/cache/config.php',
70+
);
2271
23-
Tips
24-
----
25-
- Use caching in production for best performance.
26-
- You can combine caching with any config aggregation.
72+
Choose The Right Strategy
73+
-------------------------
2774

28-
See also:
29-
- `PSR-16 Simple Cache <https://www.php-fig.org/psr/psr-16/>`_
30-
- `Live Coverage Report <../../public/coverage/index.html>`_
75+
- Use ``configCache()`` when you already have a PSR-16 cache service.
76+
- Use ``cachedConfigFile`` when you want an explicit generated file for directory or provider aggregation.
77+
- Clear or rebuild your chosen cache when configuration sources change between deployments.

docs/advanced/index.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
Advanced Topics
22
===============
33

4-
This section covers advanced usage, such as lazy loading, custom providers, and caching strategies. For implementation details, see the `GitHub repository <https://github.com/php-fast-forward/config>`_ and the `Live Coverage Report <../public/coverage/index.html>`_.
4+
These pages explain how the package behaves once you move past the first examples. They are especially useful when you want to integrate FastForward Config into a framework, optimize startup work, or control caching more precisely.
55

66
.. toctree::
77
:maxdepth: 2
88

9+
integration
910
lazy-loading
1011
providers
1112
caching

docs/advanced/integration.rst

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
Integration
2+
===========
3+
4+
This page focuses on the main integration hook exposed by the package: ``ConfigContainer``.
5+
6+
Using ConfigContainer
7+
---------------------
8+
9+
``FastForward\\Config\\Container\\ConfigContainer`` adapts any ``ConfigInterface`` instance to ``Psr\Container\ContainerInterface``.
10+
11+
.. code-block:: php
12+
13+
use FastForward\Config\ConfigInterface;
14+
use FastForward\Config\Container\ConfigContainer;
15+
use function FastForward\Config\config;
16+
17+
$config = config([
18+
'database.host' => 'localhost',
19+
'database.port' => 3306,
20+
]);
21+
22+
$container = new ConfigContainer($config);
23+
24+
$sameConfig = $container->get('config');
25+
$sameConfigAgain = $container->get(ConfigInterface::class);
26+
$host = $container->get('config.database.host');
27+
28+
Resolved Identifiers
29+
--------------------
30+
31+
.. list-table:: Identifiers handled by ConfigContainer
32+
:header-rows: 1
33+
34+
* - Identifier
35+
- Returns
36+
* - ``config``
37+
- The wrapped config object.
38+
* - ``FastForward\\Config\\ConfigInterface``
39+
- The wrapped config object.
40+
* - The concrete config class name
41+
- The wrapped config object.
42+
* - ``config.some.key``
43+
- The resolved configuration value.
44+
* - ``FastForward\\Config\\Container\\ConfigContainer``
45+
- The container wrapper itself.
46+
47+
When To Use It
48+
--------------
49+
50+
``ConfigContainer`` is most useful when:
51+
52+
- a part of your application already expects ``ContainerInterface``;
53+
- you want container-style lookup for config values such as ``config.database.host``;
54+
- you want to expose the config object itself under a stable alias.
55+
56+
Troubleshooting
57+
---------------
58+
59+
- If ``has('config.some.key')`` is false, confirm that the key exists in the wrapped config object.
60+
- If ``get()`` cannot resolve an identifier, ``ContainerNotFoundException`` is thrown.
61+
- If your application already has its own container, you can still use ``ConfigContainer`` as a small adapter or register the wrapped config object under similar service names there.

docs/advanced/lazy-loading.rst

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,57 @@
11
Lazy Loading
22
============
33

4-
FastForward Config uses lazy loading to defer the loading and merging of configuration data until it is actually needed. This is achieved via the ``__invoke()`` method on config objects, which builds the final configuration only on first access.
4+
Most config objects in this package delay work until you actually use them. This keeps bootstrap code light and lets you compose multiple sources before paying the cost of loading and merging them.
55

6-
How it works
7-
------------
6+
Which Types Are Lazy
7+
--------------------
88

9-
- When you create a config object (e.g., with ``config()`` or ``configDir()``), no files or providers are loaded immediately.
10-
- The actual loading and merging only happens when you call a method like ``get()``, ``set()``, or use the object as an array.
11-
- This is implemented via the ``LazyLoadConfigTrait`` (see `source <https://github.com/php-fast-forward/config/blob/main/src/LazyLoadConfigTrait.php>`_).
9+
The following types resolve themselves on first use:
1210

13-
Benefits
14-
--------
15-
- Faster application startup.
16-
- Only loads what you actually use.
17-
- Supports dynamic and late-bound config sources.
11+
- ``AggregateConfig``
12+
- ``DirectoryConfig``
13+
- ``RecursiveDirectoryConfig``
14+
- ``LamiasConfigAggregatorConfig``
15+
- ``CachedConfig``
16+
17+
``ArrayConfig`` is the main eager implementation because it already has all data in memory.
18+
19+
What Triggers Resolution
20+
------------------------
21+
22+
The first call to any of the operations below will build the underlying config object:
23+
24+
- ``get()``
25+
- ``has()``
26+
- ``set()``
27+
- ``remove()``
28+
- ``toArray()``
29+
- iteration with ``foreach``
30+
- array access such as ``$config['app.env']``
31+
32+
After the first resolution, the trait reuses the same internal config instance.
1833

1934
Example
2035
-------
2136

2237
.. code-block:: php
2338
24-
$config = configDir(__DIR__ . '/config');
25-
// At this point, nothing is loaded yet!
26-
$env = $config->get('app.env'); // Now the config is loaded and merged.
39+
use function FastForward\Config\configDir;
40+
41+
$config = configDir(__DIR__ . '/config', recursive: true);
42+
// No files have been merged yet.
43+
44+
$environment = $config->get('app.env');
45+
// The directory is read and merged here, on first access.
46+
47+
Why This Matters
48+
----------------
49+
50+
- Startup stays simple even when you aggregate several sources.
51+
- Errors from unreadable directories or broken providers may appear on first use instead of object creation.
52+
- You can force resolution early by calling ``toArray()`` during bootstrap if that better matches your application's error handling.
53+
54+
For Library Authors
55+
-------------------
2756

28-
See also:
29-
- `Live Coverage Report <../../public/coverage/index.html>`_
57+
The lazy behavior is implemented through ``LazyLoadConfigTrait``. This is mainly useful if you build your own ``ConfigInterface`` implementation and want it to defer work until first access.

0 commit comments

Comments
 (0)