componenta/config

Immutable configuration container with dot notation, callable support, and caching

Maintainers

Package info

github.com/componenta/config

pkg:composer/componenta/config

Statistics

Installs: 7

Dependents: 33

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-06-15 10:56 UTC

This package is auto-updated.

Last update: 2026-06-15 12:06:34 UTC


README

Immutable configuration and environment access for Componenta libraries.

Installation

composer require componenta/config

This package intentionally does not declare an automatic provider in extra.componenta.config-providers. Componenta\Config\ConfigProvider is the base class used by package and application providers.

Requirements

  • PHP 8.4+
  • componenta/var-export for cache export

Related Packages

Package Why it matters here
componenta/var-export Exports configuration into executable PHP cache files.
componenta/di Consumes the dependencies section returned by ConfigProvider classes.
componenta/app Chooses provider loading in development or cache loading in production.

What It Provides

  • Config: immutable configuration container with literal keys and ConfigPath keys.
  • Environment: immutable environment container with typed accessors.
  • ConfigLoader: static loader/exporter for provider arrays and cache files.
  • ConfigProvider: base class for modular DI configuration.
  • FileProvider: PHP/JSON file provider with Componenta merge semantics.

Loading Configuration

ConfigLoader does not decide dev/prod mode. Runtime bootstrap chooses whether to load providers or a prebuilt cache file.

use Componenta\Config\ConfigLoader;
use Componenta\Config\Environment;
use Componenta\Config\FileProvider;

$environment = new Environment($_ENV);

$config = ConfigLoader::load(
    $environment,
    new FileProvider(__DIR__ . '/config/*.php'),
    static fn(): array => ['app' => ['debug' => false]],
);

For production cache:

use Componenta\Config\ConfigLoader;

$config = ConfigLoader::loadFromFile(__DIR__ . '/var/cache/config.php', populateEnv: true);

To build cache:

use Componenta\Config\ConfigLoader;

ConfigLoader::export($config, __DIR__ . '/var/cache/config.php');

The exported file returns:

[
    'config' => [...],
    'environment' => [...],
]

Accessing Values

String keys are literal. ConfigPath keys resolve nested arrays.

use function Componenta\Config\path;

$config->get('database.host');        // literal key: $data['database.host']
$config->get(path('database.host'));  // nested key: $data['database']['host']

Typed accessors convert values or throw:

$host = $config->string(path('database.host'));
$port = $config->int(path('database.port'), 3306);
$debug = $config->bool(path('app.debug'), false);
$tags = $config->array(path('app.tags'), []);

If no default is provided, a missing key throws ConfigException. If a value cannot be converted to the requested type, InvalidConfigValueException is thrown.

Boolean Conversion

Accepted truthy values:

  • true
  • 1
  • yes
  • on
  • enabled
  • y

Accepted falsy values:

  • false
  • 0
  • no
  • off
  • disabled
  • n
  • empty string

Ambiguous values such as 42, -1, arrays, null, or unknown strings are not silently coerced to bool.

Callable Values

Callable config values receive the current Config instance and are cached after the first call by default.

use Componenta\Config\Config;
use function Componenta\Config\path;

$config = ConfigLoader::load(null, static fn(): array => [
    'database' => [
        'host' => 'localhost',
        'dsn' => static fn(Config $config): string => sprintf(
            'mysql:host=%s',
            $config->string(path('database.host')),
        ),
    ],
]);

$dsn = $config->string(path('database.dsn'));

Use flags when raw callable access or non-cached execution is needed:

$raw = $config->get(path('database.dsn'), flags: Config::NO_CALL);
$fresh = $config->string(path('database.dsn'), flags: Config::CALL_VALUES | Config::NO_CACHE);

Environment

EnvLoader loads .env* files from one or more directories and returns ?Environment.

use Componenta\Config\Loader\EnvLoader;

$environment = (new EnvLoader(__DIR__))->load(
    override: false,
    populateServer: true,
);

If no .env* files are found and no globals are available, load() returns null.

Environment keys can be strings or ConfigPath objects. Paths are converted to uppercase snake case:

$environment->string('APP_ENV', 'production');
$environment->string(path('database.host')); // DATABASE_HOST

ConfigProvider

Modules extend ConfigProvider to register DI metadata and module config.

use Componenta\Config\ConfigProvider;

final class AppConfigProvider extends ConfigProvider
{
    protected function getFactories(): array
    {
        return [
            LoggerInterface::class => LoggerFactory::class,
        ];
    }

    protected function getAliases(): array
    {
        return [
            CacheInterface::class => RedisCache::class,
        ];
    }

    protected function getConfig(): array
    {
        return [
            'app' => ['name' => 'Ophire'],
        ];
    }
}

Calling a provider returns a config array with a dependencies section.