PHPackages                             phpdot/config - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Caching](/categories/caching)
4. /
5. phpdot/config

ActiveLibrary[Caching](/categories/caching)

phpdot/config
=============

Configuration management for PHP: load, merge, resolve, cache.

v1.2.0(1w ago)0262MITPHPPHP &gt;=8.4

Since Apr 2Pushed 2mo agoCompare

[ Source](https://github.com/phpdot/config)[ Packagist](https://packagist.org/packages/phpdot/config)[ RSS](/packages/phpdot-config/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (12)Versions (7)Used By (2)

phpdot/config
=============

[](#phpdotconfig)

Configuration management for PHP: load, merge, resolve, cache.

Install
-------

[](#install)

```
composer require phpdot/config
```

Zero dependencies. Pure PHP 8.3+.

Quick Start
-----------

[](#quick-start)

```
use PHPdot\Config\Configuration;

$config = new Configuration(path: __DIR__ . '/config');

$config->get('database.host');                // 'localhost'
$config->get('database.port');                // 3306
$config->get('database.missing', 'default');  // 'default'
```

---

Architecture
------------

[](#architecture)

 ```
graph TD
    FILES["config/*.php filesEach file returns an array.The lowercased filename becomesthe section name."]

    subgraph Pipeline
        direction TB
        LOAD["ConfigLoaderScans directory, requires each file"]
        MERGE["ConfigMergerOverlays the active environment'svalues onto the base section"]
        RESOLVE["ConfigResolverExecutes closures and resolvessection.key placeholders"]
        LOAD --> MERGE --> RESOLVE
    end

    CFG["ConfigurationFlattens to dot-notation,exposes get / has / section /typed getters / dto."]

    CACHE["ConfigCacheOptional. Dumps the resolvedtree to a single PHP file forproduction fast-boot."]

    FILES --> Pipeline
    Pipeline --> CFG
    CFG -.optional.-> CACHE
```

      Loading ---

Config Files
------------

[](#config-files)

Each file in the config directory returns an array. The lowercased filename (without `.php`) becomes the section name — `Database.php` and `database.php` both yield section `database`.

```
// config/database.php
return [
    'host' => 'localhost',
    'port' => 3306,
    'name' => 'myapp',
    'username' => 'root',
    'password' => '',
];
```

Access with dot notation:

```
$config->get('database.host');              // 'localhost'
$config->get('database.port');              // 3306
$config->get('database.options.timeout');   // nested values work too
```

---

Environment Overrides
---------------------

[](#environment-overrides)

Config files can include environment-specific overrides as top-level keys:

```
// config/database.php
return [
    'host' => 'localhost',
    'port' => 3306,
    'debug' => true,

    'staging' => [
        'host' => 'staging-db.internal',
    ],

    'production' => [
        'host' => 'prod-db.internal',
        'port' => 5432,
        'debug' => false,
    ],
];
```

```
$config = new Configuration(
    path: __DIR__ . '/config',
    environment: 'production',
    environments: ['development', 'staging', 'production'],
);

$config->get('database.host');   // 'prod-db.internal' (overridden)
$config->get('database.port');   // 5432 (overridden)
$config->get('database.debug');  // false (overridden)
$config->get('database.name');   // 'myapp' (inherited from base)
```

Values not overridden are inherited from base. Environment keys are removed from the result.

---

Placeholders
------------

[](#placeholders)

Reference values from other sections with `{section.key}` syntax:

```
// config/app.php
return [
    'name' => 'MyApp',
    'url' => 'https://myapp.com',
];

// config/mail.php
return [
    'from_name' => '{app.name}',
    'footer' => 'Sent from {app.name}',
];

// config/services.php
return [
    'api_base' => '{app.url}/api/v1',
    'webhook' => '{services.api_base}/webhooks',  // chained
];
```

```
$config->get('mail.from_name');     // 'MyApp'
$config->get('services.webhook');   // 'https://myapp.com/api/v1/webhooks'
```

Unresolvable placeholders are left as-is. No errors thrown.

---

Dynamic Values
--------------

[](#dynamic-values)

Closures are executed once during resolution:

```
return [
    'secret' => fn() => bin2hex(random_bytes(32)),
    'boot_time' => fn() => date('Y-m-d H:i:s'),
];
```

---

DTO Hydration
-------------

[](#dto-hydration)

Auto-hydrate any class from a config section:

```
readonly class DatabaseConfig
{
    public function __construct(
        public string $host,
        public int $port,
        public string $name,
        public string $username,
        public string $password = '',
        public bool $debug = false,
    ) {}
}

$db = $config->dto('database', DatabaseConfig::class);
$db->host;    // 'prod-db.internal'
$db->port;    // 5432 (int, auto-cast)
$db->debug;   // false (bool, auto-cast)
```

No base class needed. No interface needed. Config keys matched to constructor parameter names. Types auto-cast for scalars. Parameters with defaults are optional. Cached per section+class.

### Nested DTOs

[](#nested-dtos)

When a constructor parameter is typed as a class and the matching value is an array, the array is recursively hydrated into that class. One section can drive multiple typed sub-DTOs:

```
readonly class CookieConfig
{
    public function __construct(
        public bool $secure = true,
        public bool $httpOnly = true,
        public string $sameSite = 'Lax',
    ) {}
}

readonly class HttpConfig
{
    /**
     * @param list $trustedProxies
     */
    public function __construct(
        public array $trustedProxies = [],
        public int $trustedHeaders = 0,
        public CookieConfig $cookie = new CookieConfig(),
    ) {}
}
```

```
// config/http.php
return [
    'trustedProxies' => ['10.0.0.0/8'],
    'trustedHeaders' => 31,
    'cookie' => [
        'secure'   => true,
        'sameSite' => 'Strict',
    ],
];
```

```
$http = $config->dto('http', HttpConfig::class);
$http->cookie->secure;     // true
$http->cookie->sameSite;   // 'Strict'
$http->cookie->httpOnly;   // true (default — key absent in config file)
```

Recursion is unbounded — multi-level nesting works the same way. Missing inner keys throw `InvalidArgumentException` (unless the parameter has a default).

---

Caching
-------

[](#caching)

Skip parsing in production:

```
// Production — cached
$config = new Configuration(
    path: __DIR__ . '/config',
    environment: 'production',
    environments: ['development', 'staging', 'production'],
    cachePath: __DIR__ . '/storage/cache/config.php',
);

// First request: loads, merges, resolves, writes cache
// Subsequent requests: single require from cache (opcache-friendly)
```

```
// CLI: clear cache on deploy
ConfigCache::clear(__DIR__ . '/storage/cache/config.php');
```

---

Full API
--------

[](#full-api)

```
// Generic getter
$config->get('key', $default);                    // mixed value or default
$config->has('key');                              // bool

// Typed getters — coerce to the requested type, fall back to default if mismatched
$config->string('database.host', 'localhost');    // string
$config->integer('database.port', 3306);          // int (parses numeric strings)
$config->float('rate.threshold', 1.0);            // float
$config->boolean('database.debug', false);        // bool — accepts true/false/1/0/yes/no/on/off
$config->array('cache.servers', []);              // array

// Aggregate access
$config->section('database');                     // full nested array for the section
$config->sections();                              // ['app', 'cache', 'database', ...]
$config->search('database');                      // all database.* keys
$config->search('database', stripPrefix: true);   // same, prefix removed
$config->all();                                   // all flattened key-value pairs

// DTO hydration (single + nested)
$config->dto('database', DbConfig::class);        // hydrate a typed DTO

// Lifecycle
$config->reload();                                // re-run pipeline (clears any cache)
$config->getEnvironment();                        // current environment name
$config->getPath();                               // config directory path
```

---

Package Structure
-----------------

[](#package-structure)

```
src/
├── Configuration.php          Main entry point
├── ConfigCache.php            Cache read/write/clear
├── Loader/
│   └── ConfigLoader.php       Directory scanner
├── Merger/
│   └── ConfigMerger.php       Environment override merging
├── Resolver/
│   └── ConfigResolver.php     Closures + placeholder resolution
├── Util/
│   └── Arr.php                Internal array helpers
└── Exception/
    ├── ConfigException.php    Base exception
    ├── ConfigLoaderException.php
    └── ConfigCacheException.php

```

---

Development
-----------

[](#development)

```
composer test        # PHPUnit (114 tests)
composer analyse     # PHPStan level 10
composer cs-fix      # PHP-CS-Fixer
composer check       # All three
```

License
-------

[](#license)

MIT

###  Health Score

44

↑

FairBetter than 90% of packages

Maintenance92

Actively maintained with recent releases

Popularity9

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity56

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~17 days

Total

6

Last Release

8d ago

PHP version history (2 changes)v1.0.0PHP &gt;=8.3

v1.2.0PHP &gt;=8.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/62e82421bda4b5d6ba9a47ba6d88caca060dcd0d1a2862f351f3a97657385db0?d=identicon)[phpdot](/maintainers/phpdot)

---

Top Contributors

[![phpdot](https://avatars.githubusercontent.com/u/252500?v=4)](https://github.com/phpdot "phpdot (5 commits)")

---

Tags

configurationconfigcacheenvironmentdto

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/phpdot-config/health.svg)

```
[![Health](https://phpackages.com/badges/phpdot-config/health.svg)](https://phpackages.com/packages/phpdot-config)
```

###  Alternatives

[duncan3dc/helpers

A collection of useful helper classes

13188.1k](/packages/duncan3dc-helpers)[corneltek/configkit

Fast config toolkit, which provides super lightweight config accessor and loader.

1314.2k8](/packages/corneltek-configkit)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
