spiral/config
Spiral Config provides a flexible configuration system for Spiral apps. Load, merge, and access settings from multiple sources with a clean API, supporting layered environments and structured config classes for predictable, testable application configuration.
Start by installing the package via Composer (composer require spiral/config). Create a basic config directory (e.g., config/) and define your first config file as PHP-returning-array (e.g., config/app.php returning ['name' => 'MyApp', 'version' => '1.0']). In your app bootstrap, instantiate a ConfigManager and add a source:
use Spiral\Config\ConfigManager;
use Spiral\Config\Loader\PhpLoader;
$manager = new ConfigManager(new PhpLoader(__DIR__ . '/config'));
$config = $manager->getConfig('app');
echo $config->get('name'); // 'MyApp'
The first use case is typically centralizing app constants (e.g., app name, debug mode, feature flags) — replacing scattered env() calls and untyped globals.
config/database.php, config/cache.php). Access via $config->get('database.connections.mysql') using dot-notation.$manager->addLoader(new PhpLoader(__DIR__ . '/config/env'), priority: 10);
Files like config/env/production/database.php override base values.env() only in a thin config/bridge.php to translate .env keys to PHP arrays, then expose via ConfigManager:
// config/bridge.php
return [
'app' => [
'debug' => filter_var($_ENV['APP_DEBUG'] ?? 'false', FILTER_VALIDATE_BOOLEAN),
],
];
$manager->getCacheable()->export() into a PHP file, and load it in production via ArrayLoader to avoid runtime parsing.$config in a dedicated ConfigService or dependency-injection container to avoid tight coupling with ConfigManager.set() returns a new config instance — do not expect in-place changes. Use withConfig() or DI factories for runtime overrides.ConfigManager::addLoader($loader, $priority) to control precedence; default priority is 0.['db' => [0 => [...] ]]) won’t parse as db.0.connection.$_ENV values are strings. Always cast explicitly (e.g., (int)$_ENV['PORT']) in bridge loaders — config package won’t auto-convert.my_package.timeout instead of timeout).ConfigInterface directly in tests instead of ConfigManager for speed and isolation. Use $this->mock(ConfigInterface::class)->method('get')->with('key')->willReturn('value');How can I help you explore Laravel packages today?