hassankhan/config
Lightweight PHP config loader (PHP 7.4+) for files or strings. Supports PHP, INI, XML, JSON, YAML (via Symfony Yaml), Properties and serialized formats. Load single/multiple files or directories, optional files, and get/set values with simple API.
Start by installing via Composer:
composer require hassankhan/config
For YAML support, also require symfony/yaml:
composer require symfony/yaml
Load your config with one line—no need to manually parse:
use Noodlehaus\Config;
$config = Config::load('config.json');
// or
$config = new Config(['config.dist.php', '?config.local.php']);
The package automatically detects parsers by file extension (.json, .ini, .yaml, .xml, .php, .properties, .ser), and optional files (prefixed with ?) are skipped if missing.
First use case: load environment-specific overrides in order of precedence:
$config = new Config([
'config.php', // defaults
'?config.local.php', // local override (ignored if missing)
]);
Layered configuration: Use multiple files or directories to separate concerns (e.g., app.json, db.json, cache.yaml). Load them in priority order:
$config = new Config(['config.php', 'secrets.php']);
Dynamic config sources: Load from strings (e.g., secrets from environment or vaults):
$json = getenv('APP_CONFIG_JSON');
$config = Config::load($json, new \Noodlehaus\Parser\Json(), true);
Directory-based configs: Load all .json/.yaml files in a directory:
$config = new Config(__DIR__ . '/config');
// Files are loaded alphabetically; later files override earlier ones
In-memory config without files: Extend AbstractConfig for compile-time defaults (e.g., bundle defaults):
class AppConfig extends \Noodlehaus\AbstractConfig {
protected function getDefaults(): array {
return ['app.name' => 'MyApp', 'debug' => false];
}
}
$config = new AppConfig();
Export to other formats: Convert loaded config for external systems (e.g., dump to INI for CLI tools):
$config->toFile('output.ini', new \Noodlehaus\Parser\Ini());
Merge configs: Combine runtime-loaded configs (e.g., package defaults + user config):
$defaults = Config::load('vendor/config.json');
$user = Config::load('~/.myapp/config.json');
$defaults->merge($user);
set() is ephemeral: Config::set() or array assignment ($config['key'] = 'value') modifies memory only—changes are not persisted. To persist, use toFile().
PHP format ≠ safe: Avoid loading .php configs from untrusted sources—they execute arbitrary code. Prefer JSON/YAML for user-provided files.
YAML performance: YAML parsing is ~5× slower than JSON/PHP. Profile before committing to YAML in hot paths.
has() vs get() with null: has('key.with.null') returns true if the key exists and is null. Don’t use isset($config['key'])—ArrayAccess implementation handles this correctly.
Nested keys use dot notation: 'app.db.host' resolves to $config['app']['db']['host']. No need for nested arrays in keys.
Extension-based auto-detection: Ensure file extensions match supported types. .yml is treated the same as .yaml, but .config won’t auto-detect unless you pass a parser.
Optional path prefix: Use ?file.json to safely handle optional config files (e.g., .env.local) without guarding with file_exists().
Extensibility points: Implement ParserInterface or WriterInterface to support custom formats (e.g., TOML, HCL). Check tests/mocks/pass for valid format examples.
Debug tip: Use $config->all() to inspect loaded config, but note merging order—later sources override earlier ones, and directory loading is alphabetical.
How can I help you explore Laravel packages today?