vaibhavpandeyvpz / kunfig
Helper library to easily merge & use multiple configuration files.
Installs: 136
Dependents: 1
Suggesters: 0
Security: 0
Stars: 2
Watchers: 1
Forks: 0
Open Issues: 0
pkg:composer/vaibhavpandeyvpz/kunfig
Requires
- php: ^8.2
Requires (Dev)
- phpunit/phpunit: ^10.0
This package is auto-updated.
Last update: 2025-12-31 09:16:55 UTC
README
A modern, flexible PHP configuration management library that provides multiple access patterns for managing configuration values with support for nested configurations, merging, and type safety.
Features
- 🎯 Multiple Access Patterns: Access configuration values using methods, array syntax, or object properties
- 🔄 Nested Configurations: Automatic conversion of arrays to nested
Configinstances - 🔀 Configuration Merging: Recursively merge multiple configurations with
mix() - 📝 Dot Notation: Access nested values using dot syntax (e.g.,
$config->get('app.debug')) - 🔒 Type Safety: Full PHP 8.2+ type declarations with strict types
- 📊 Iterable & Countable: Implements
IteratorAggregateandCountableinterfaces - 🎨 Modern PHP: Built with PHP 8.2+ features including traits, union types, and more
- ✅ 100% Test Coverage: Comprehensive test suite with full code coverage
Requirements
- PHP 8.2 or higher
Installation
Install via Composer:
composer require vaibhavpandeyvpz/kunfig
Quick Start
<?php use Kunfig\Config; // Create a configuration instance $config = new Config([ 'database' => [ 'host' => 'localhost', 'port' => 3306, 'name' => 'myapp', ], 'app' => [ 'name' => 'My Application', 'debug' => false, ], ]); // Access values using object properties echo $config->database->host; // 'localhost' // Access values using array syntax echo $config['app']['name']; // 'My Application' // Access values using dot notation echo $config->get('app.name'); // 'My Application' echo $config['database.host']; // 'localhost' // Access values using methods echo $config->get('database')->get('port'); // 3306
Usage Examples
Basic Operations
Creating a Configuration
use Kunfig\Config; // Empty configuration $config = new Config(); // With initial values $config = new Config([ 'key' => 'value', 'nested' => [ 'deep' => 'value', ], ]);
Getting Values
// Method access $value = $config->get('key'); $value = $config->get('nonexistent', 'default'); // with fallback // Property access $value = $config->key; $nested = $config->nested->deep; // Array access $value = $config['key']; $nested = $config['nested']['deep']; // Dot notation (alternative to nested access) $nested = $config->get('nested.deep'); $nested = $config['nested.deep']; $value = $config->get('app.database.host', 'localhost'); // with fallback
Setting Values
// Method access $config->set('key', 'value'); $config->set('nested', ['deep' => 'value']); // Property access $config->key = 'value'; $config->nested = new Config(['deep' => 'value']); // Array access $config['key'] = 'value'; $config['nested'] = ['deep' => 'value']; // Dot notation (creates nested structure automatically) $config->set('app.debug', true); $config['database.host'] = 'localhost'; $config->set('app.database.port', 3306); // creates nested structure // Arrays are automatically converted to Config instances $config->set('database', ['host' => 'localhost']); $config->database->host; // 'localhost' (automatically a Config instance)
Checking Existence
// Method access if ($config->has('key')) { // key exists } // Property access if (isset($config->key)) { // key exists } // Array access if (isset($config['key'])) { // key exists } // Dot notation if ($config->has('app.debug')) { // nested key exists } if (isset($config['app.debug'])) { // nested key exists }
Removing Values
// Method access $config->remove('key'); // Property access unset($config->key); // Array access unset($config['key']); // Dot notation $config->remove('app.debug'); unset($config['database.host']);
Dot Notation
Kunfig supports dot notation for accessing nested configuration values, providing a convenient alternative to chained property or array access.
Basic Usage
$config = new Config([ 'app' => [ 'name' => 'MyApp', 'debug' => false, 'database' => [ 'host' => 'localhost', 'port' => 3306, ], ], ]); // Instead of: $config->app->database->host $host = $config->get('app.database.host'); // 'localhost' // Instead of: $config['app']['database']['port'] $port = $config['app.database.port']; // 3306 // With fallback $timeout = $config->get('app.database.timeout', 30); // 30 (default)
Setting Nested Values
Dot notation automatically creates the nested structure when setting values:
$config = new Config(); // Creates nested structure automatically $config->set('app.debug', true); $config['app.database.host'] = 'localhost'; $config->set('app.database.port', 3306); // Now accessible via all methods $config->app->debug; // true $config['app']['database']['host']; // 'localhost' $config->get('app.database.port'); // 3306
Checking Existence
// Check nested keys if ($config->has('app.debug')) { // app.debug exists } if (isset($config['app.database.host'])) { // app.database.host exists }
Removing Nested Values
// Remove nested keys $config->remove('app.debug'); unset($config['app.database.port']); // Remove entire nested branches $config->remove('app.database'); // removes entire database config
Deeply Nested Access
Dot notation works with any depth of nesting:
$config = new Config([ 'level1' => [ 'level2' => [ 'level3' => [ 'level4' => 'deep_value', ], ], ], ]); // Access deeply nested values $value = $config->get('level1.level2.level3.level4'); // 'deep_value' $config->set('level1.level2.level3.level4.new', 'value');
Edge Cases
$config = new Config([ 'app' => 'simple_string', // non-config value ]); // Accessing nested key on non-config value returns fallback $value = $config->get('app.key', 'default'); // 'default' // Setting nested key on non-config value converts it to Config $config->set('app.key', 'value'); $config->get('app'); // Returns ConfigInterface instance $config->get('app.key'); // 'value'
Merging Configurations
The mix() method allows you to merge configurations, with values from the source configuration overriding existing values. Nested configurations are recursively merged.
$base = new Config([ 'database' => [ 'host' => 'localhost', 'port' => 3306, 'name' => 'production', ], 'app' => [ 'name' => 'My App', 'debug' => false, ], ]); $override = new Config([ 'database' => [ 'port' => 5432, // Override port 'name' => 'staging', // Override name // host remains 'localhost' ], 'app' => [ 'debug' => true, // Override debug // name remains 'My App' ], 'cache' => [ 'enabled' => true, // New key ], ]); $base->mix($override); // Result: // $base->database->host === 'localhost' (unchanged) // $base->database->port === 5432 (overridden) // $base->database->name === 'staging' (overridden) // $base->app->name === 'My App' (unchanged) // $base->app->debug === true (overridden) // $base->cache->enabled === true (new)
Iterating Over Configuration
Since Config implements IteratorAggregate, you can iterate over configuration values:
$config = new Config([ 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3', ]); foreach ($config as $key => $value) { echo "$key: $value\n"; }
Getting All Values
The all() method returns all configuration values as a plain array, recursively converting nested Config instances:
$config = new Config([ 'app' => [ 'name' => 'My App', 'version' => '1.0.0', ], 'debug' => false, ]); $array = $config->all(); // Returns: // [ // 'app' => [ // 'name' => 'My App', // 'version' => '1.0.0', // ], // 'debug' => false, // ]
Counting Configuration Items
Since Config implements Countable, you can use count():
$config = new Config([ 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3', ]); echo count($config); // 3
Real-World Example
<?php use Kunfig\Config; // Load base configuration $config = new Config([ 'database' => [ 'host' => 'localhost', 'port' => 3306, 'charset' => 'utf8mb4', ], 'cache' => [ 'driver' => 'file', 'ttl' => 3600, ], ]); // Load environment-specific overrides $envConfig = new Config([ 'database' => [ 'host' => getenv('DB_HOST') ?: 'localhost', 'name' => getenv('DB_NAME') ?: 'myapp', 'user' => getenv('DB_USER') ?: 'root', 'password' => getenv('DB_PASSWORD') ?: '', ], 'cache' => [ 'ttl' => 7200, // Override TTL ], ]); // Merge configurations $config->mix($envConfig); // Use the configuration (multiple access patterns) $pdo = new PDO( sprintf( "mysql:host=%s;port=%d;dbname=%s;charset=%s", $config->database->host, // Property access $config->get('database.port'), // Dot notation $config['database']['name'], // Array access $config->get('database')->get('charset') // Method chaining ), $config->get('database.user'), // Dot notation $config->database->password // Property access );
API Reference
ConfigInterface
The main interface that defines the configuration contract.
Methods
all(): array- Get all configuration values as an arrayhas(string $key): bool- Check if a key exists (supports dot notation)get(string $key, mixed $fallback = null): mixed- Get a value by key (supports dot notation)set(string $key, mixed $value): void- Set a value (supports dot notation, creates nested structure)remove(string $key): void- Remove a key (supports dot notation)mix(ConfigInterface $config): void- Merge another configuration
Implemented Interfaces
ArrayAccess- Array-like access ($config['key']or$config['app.debug']with dot notation)Countable- Count items (count($config))IteratorAggregate- Iterate over values (foreach ($config as ...))
Config
The main configuration class implementing ConfigInterface.
Constructor
public function __construct(array $values = [])
Creates a new Config instance. Array values are automatically converted to nested Config instances.
Static Methods
public static function __set_state(array $data): static
Creates a new instance from an exported array (for var_export() compatibility).
ConfigTrait
A trait that provides default implementations for ArrayAccess and property access methods. Can be used by any class implementing ConfigInterface.
Advanced Usage
Custom Configuration Classes
You can create custom configuration classes by implementing ConfigInterface and using ConfigTrait:
use Kunfig\ConfigInterface; use Kunfig\ConfigTrait; class MyCustomConfig implements ConfigInterface { use ConfigTrait; protected array $values = []; // Implement required methods... public function all(): array { /* ... */ } public function has(string $key): bool { /* ... */ } // ... etc }
Type-Safe Configuration
With PHP 8.2+ type declarations, you get full type safety:
$config = new Config([ 'port' => 3306, ]); // Type-safe access $port = $config->get('port', 0); // int $host = $config->get('host', 'localhost'); // string
Handling Different Value Types
$config = new Config([ 'string' => 'text', 'integer' => 42, 'float' => 3.14, 'boolean' => true, 'null' => null, 'array' => ['nested' => 'value'], ]); // All types are preserved $config->string; // string $config->integer; // int $config->float; // float $config->boolean; // bool $config->null; // null $config->array; // ConfigInterface instance
Testing
The project maintains 100% code coverage. Run tests with:
# Run tests vendor/bin/phpunit # Run tests with coverage XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-text
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is open-sourced software licensed under the MIT license.