PHPackages                             camoo/config-interop - 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. [PSR &amp; Standards](/categories/psr-standards)
4. /
5. camoo/config-interop

ActiveLibrary[PSR &amp; Standards](/categories/psr-standards)

camoo/config-interop
====================

Common interface for immutable configuration access and interoperability.

0.1.0(4w ago)06MITPHPPHP &gt;=8.2

Since May 11Pushed 4w agoCompare

[ Source](https://github.com/camoo/config-interop)[ Packagist](https://packagist.org/packages/camoo/config-interop)[ Docs](https://github.com/camoo/config-interop)[ RSS](/packages/camoo-config-interop/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)Dependencies (3)Versions (4)Used By (0)

Config Interoperability Draft — Common Interface for Configuration Access
=========================================================================

[](#config-interoperability-draft--common-interface-for-configuration-access)

> ⚠️ **Draft Proposal** — This is a pre-submission draft for the PHP-FIG PSR process. The interfaces and specification are subject to change.

[![PHP 8.2+](https://camo.githubusercontent.com/744f8821cc27dec8b0013ade48179731a44eadf4f943e0b1d9ffcb93f80177de/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d382e322532422d626c75652e737667)](https://php.net)[![License: MIT](https://camo.githubusercontent.com/784362b26e4b3546254f1893e778ba64616e362bd6ac791991d2c9e880a3a64e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e2e737667)](LICENSE)

---

What Is This?
-------------

[](#what-is-this)

This repository houses a **PHP-FIG draft proposal** for a minimal, immutable, framework-agnostic configuration interface: **Config Proposal**.

The goal is to let libraries, packages, and frameworks accept configuration through a single shared interface — without coupling either side to a specific framework or implementation.

---

The Problem
-----------

[](#the-problem)

Every major PHP framework ships its own configuration container:

FrameworkClassMutable?Framework-coupled?Symfony`ParameterBag`✅✅Laravel`Illuminate\Config\Repository`✅✅Laminas`Laminas\Config\Config`OptionalPartiallyNette`ArrayHash`✅PartiallyA library author who needs to read a `database.host` value must today either:

- Accept a raw `array` (no type safety, no IDE support, no contract),
- Couple to a specific framework's container, or
- Invent their own interface (fragmentation).

This proposal solves this by defining the **smallest possible read-only interface** that every framework can implement without sacrificing its own model.

---

The Interfaces
--------------

[](#the-interfaces)

```
namespace ConfigInterop;

interface ConfigInterface
{
    /** Implementations MUST return false when the stored value is null. */
    public function has(string $key): bool;
    public function get(string $key, mixed $default = null): mixed;

    /** @return array */
    public function all(): array;

    public function withPrefix(string $prefix): static;
}

interface ConfigProviderInterface
{
    public function getConfig(): ConfigInterface;
}
```

That's it. Four methods, zero runtime dependencies, PHP 8.2+.

`has()` checks key existence, even when the stored value is `null`.

---

Key Design Principles
---------------------

[](#key-design-principles)

PrincipleWhat it means**Immutable**No `set()`, `merge()`, or `push()` — the interface is read-only**Framework-neutral**Zero dependencies; works in any PHP project**Static-analysis-friendly**PHPDoc on every member; `static` return preserves concrete types**Minimal surface**Four methods cover all practical read use-cases**Prefix scoping**`withPrefix('db')` scopes keys: `get('host')` → `db.host`---

Repository Layout
-----------------

[](#repository-layout)

```
psr-config/
├── src/
│   ├── ConfigInterface.php           # Primary read interface
│   └── ConfigProviderInterface.php   # Factory / provider interface
├── docs/
│   └── config-interop-draft.md       # Full PSR draft document
├── examples/
│   ├── ArrayConfig.php               # Array-backed reference implementation
│   ├── EnvConfig.php                 # Environment-variable-backed implementation
│   ├── CachedConfigDecorator.php     # Caching decorator
│   ├── PrefixedConfig.php            # withPrefix() delegation example
│   └── LazyConfigProvider.php        # Deferred-instantiation provider
├── tests/
│   └── ConfigInterfaceComplianceTest.php
├── composer.json
├── CONTRIBUTING.md
└── LICENSE

```

---

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

[](#quick-start)

```
composer require camoo/config-interop
```

### Array-backed config

[](#array-backed-config)

```
use ConfigInterop\Example\ArrayConfig;

$config = new ArrayConfig([
    'database' => [
        'host' => 'localhost',
        'port' => 5432,
    ],
    'cache' => [
        'enabled' => true,
        'ttl' => 3600,
    ],
]);

$config->get('database.host');          // 'localhost'
$config->has('database.port');          // true

$db = $config->withPrefix('database');
$db->get('host');                       // 'localhost'
$db->get('missing', 'default');         // 'default'
```

### Env-backed config

[](#env-backed-config)

```
use ConfigInterop\Example\EnvConfig;

// Reads APP_DATABASE_HOST, APP_DATABASE_PORT, etc.
$config = new EnvConfig(envPrefix: 'APP_');
$config->get('database.host');
```

### Caching decorator

[](#caching-decorator)

```
use ConfigInterop\Example\CachedConfigDecorator;

$config = new CachedConfigDecorator($expensiveConfig);
// Each key resolved at most once per instance lifetime.
```

### Lazy provider

[](#lazy-provider)

```
use ConfigInterop\Example\LazyConfigProvider;
use ConfigInterop\Example\ArrayConfig;

$provider = new LazyConfigProvider(
    static fn () => new ArrayConfig(require 'config.php')
);

// Config file is not loaded until this call:
$config = $provider->getConfig();
```

---

Library Authors — How to Accept Config
--------------------------------------

[](#library-authors--how-to-accept-config)

Accept `ConfigInterface` directly — do **not** depend on specific implementations:

```
use ConfigInterop\ConfigInterface;

class DatabaseConnection
{
    public function __construct(private readonly ConfigInterface $config) {}

    public function connect(): \PDO
    {
        $db = $this->config->withPrefix('database');

        return new \PDO(
            dsn:      sprintf('pgsql:host=%s;dbname=%s', $db->get('host'), $db->get('name')),
            username: $db->get('user'),
            password: $db->get('password'),
        );
    }
}
```

---

Running Tests &amp; Static Analysis
-----------------------------------

[](#running-tests--static-analysis)

```
composer install
composer test       # PHPUnit 11
composer analyse    # PHPStan level 9
composer check      # both
```

---

The Full PSR Proposal
---------------------

[](#the-full-psr-proposal)

See [`docs/config-interop-draft.md`](docs/config-interop-draft.md) for the complete specification, including:

- Behavioral requirements (MUST / SHOULD / MAY)
- Immutability guarantees
- Prefix scoping semantics
- Error handling recommendations
- Security &amp; performance considerations
- Prior art &amp; ecosystem comparison
- FAQ

---

Contributing
------------

[](#contributing)

Please read [CONTRIBUTING.md](CONTRIBUTING.md) before opening a pull request or issue.

---

License
-------

[](#license)

MIT © Camoo SARL. See [LICENSE](LICENSE) for details.

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance94

Actively maintained with recent releases

Popularity6

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity38

Early-stage or recently created project

 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

Unknown

Total

1

Last Release

29d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/aba0dd2dc958996c6554903496744826ada2ea5c5f6370f413dcfdde7bddc56c?d=identicon)[camoo](/maintainers/camoo)

---

Top Contributors

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

---

Tags

psrinteroperabilityconfigurationconfigimmutable

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

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

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

###  Alternatives

[psr/container

Common Container Interface (PHP FIG PSR-11)

10.0k1.0B4.4k](/packages/psr-container)[symfony/translation-contracts

Generic abstractions related to translation

2.6k730.8M596](/packages/symfony-translation-contracts)[symfony/cache-contracts

Generic abstractions related to caching

2.4k324.3M286](/packages/symfony-cache-contracts)[symfony/http-client-contracts

Generic abstractions related to HTTP clients

2.0k419.3M382](/packages/symfony-http-client-contracts)[symfony/contracts

A set of abstractions extracted out of the Symfony components

3.9k65.5M127](/packages/symfony-contracts)[psr/clock

Common interface for reading the clock.

644362.7M462](/packages/psr-clock)

PHPackages © 2026

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