https://github.com/denzyldick/php-config
Load YAML, JSON, XML, or PHP config files and validate them against PHP 8.2 attribute-based DTOs.
https://github.com/denzyldick/php-config
attributes config configuration dto json php schema validation xml yaml
Last synced: about 5 hours ago
JSON representation
Load YAML, JSON, XML, or PHP config files and validate them against PHP 8.2 attribute-based DTOs.
- Host: GitHub
- URL: https://github.com/denzyldick/php-config
- Owner: denzyldick
- Created: 2026-06-14T06:57:39.000Z (27 days ago)
- Default Branch: master
- Last Pushed: 2026-06-14T08:24:48.000Z (27 days ago)
- Last Synced: 2026-06-14T09:06:05.542Z (27 days ago)
- Topics: attributes, config, configuration, dto, json, php, schema, validation, xml, yaml
- Language: PHP
- Homepage:
- Size: 11 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# php-config
Schema-based config loader for PHP. Load YAML, JSON, XML, or PHP config files and validate them against PHP 8.2 attribute-based DTOs.
## Installation
```bash
composer require denzyl/php-config
```
## Usage
Define a DTO with attributes:
```php
use PhpConfig\Attribute\Required;
use PhpConfig\Attribute\Range;
use PhpConfig\Attribute\DefaultValue;
use PhpConfig\Attribute\Nested;
class DatabaseConfig
{
#[Required]
public string $host;
#[Required]
#[Range(1, 65535)]
public int $port;
#[DefaultValue('root')]
public string $username;
#[Required]
public string $password;
#[DefaultValue(false)]
public bool $ssl;
#[Nested]
public LogConfig $log;
}
```
Load and validate — three ways to handle the result:
```php
use PhpConfig\Config;
use PhpConfig\Exception\ValidationException;
$result = Config::load('config/database.yaml', DatabaseConfig::class);
// 1. Unwrap — throws on failure (simplest)
$config = $result->unwrap(); // ValidationException on error
// 2. Guard — check and return early
if ($result->isErr()) {
$errors = $result->exception()->getErrors();
// log, display, or rethrow
}
// 3. Match — handle both branches inline (functional style)
$result->match(
fn(DatabaseConfig $config) => bootstrap($config),
fn(ValidationException $e) => handleErrors($e->getErrors()),
);
```
### Real-world example
```php
// public/index.php
use PhpConfig\Config;
$config = Config::load('../config/app.yaml', AppConfig::class)
->unwrap(); // fails hard — config errors at deploy time, not runtime
$app = new App($config);
$app->run();
```
```php
// src/App.php
use PhpConfig\Config;
use PhpConfig\Exception\ValidationException;
class App
{
public function __construct(
private readonly AppConfig $config,
) {}
public static function bootstrap(string $configPath): self
{
$result = Config::load($configPath, AppConfig::class);
if ($result->isErr()) {
$errors = $result->exception()->getErrors();
$messages = array_map(
fn($e) => "{$e->path}: {$e->message}",
$errors,
);
throw new \RuntimeException(
"Config validation failed:\n" . implode("\n", $messages),
);
}
return new self($result->unwrap());
}
}
```
```php
// config/app.yaml
database:
host: localhost
port: 3306
username: root
password: secret
ssl: false
```
## Supported formats
| Format | Extension | Reader |
|--------|-----------|--------|
| YAML | `.yaml`, `.yml` | `symfony/yaml` |
| JSON | `.json` | `ext-json` |
| XML | `.xml` | `ext-simplexml` |
| PHP | `.php` | `require` + `return` |
## Attributes
| Attribute | Description |
|-----------|-------------|
| `#[Required]` | Field must be present and non-null |
| `#[Range(min, max)]` | Numeric range constraint |
| `#[Length(min, max)]` | String length constraint |
| `#[Regex(pattern)]` | String pattern match |
| `#[Email]` | Valid email format |
| `#[Url]` | Valid URL format |
| `#[DefaultValue(value)]` | Default value when absent |
| `#[Nested]` | Nested DTO (class inferred from property type) |
## Code generation
Generate DTO classes from an existing config file — useful when migrating or scaffolding.
### CLI
```bash
vendor/bin/php-config generate:class config/database.yaml --class=DatabaseConfig
vendor/bin/php-config generate:class config/app.json --output=src/Config/
```
Options:
| Option | Description |
|--------|-------------|
| `--class=` | Class name (default: `AppConfig`) |
| `--namespace=` | Namespace (default: `App\Config`) |
| `--output=` | Write files to directory (default: stdout) |
### Programmatic
```php
use PhpConfig\Generator\SchemaGenerator;
$generator = new SchemaGenerator();
$files = $generator->generateFromFile('config/database.yaml', 'DatabaseConfig');
// Inspect or write
foreach ($files as $filename => $code) {
echo $code;
}
```
Nested objects produce separate class files. Types are inferred from values: `string`, `int`, `float`, `bool`, nested `object`, or `array`. All scalar fields get `#[Required]` — remove it on fields that are optional.
## License
MIT