puff / config
Puff Fast dot-notation configuration repository
Requires
- php: ^8.2
- composer-runtime-api: ^2.0
- puff/di: dev-main
Requires (Dev)
- phpunit/phpunit: ^11.0
This package is auto-updated.
Last update: 2026-08-20 02:54:33 UTC
README
A lightweight dot-notation configuration repository for Puff, with support for PHP configuration files, .env files, and process environment variables.
Requirements
- PHP 8.2 or later
- Composer 2
Installation
composer require puff/config
The package exposes Puff\Config\ServiceProvider through Puff's Composer auto-discovery mechanism. The provider locates the Composer root package and loads:
<project-root>/config/config.php
<project-root>/config/*.php
<project-root>/config/**/*.php
<project-root>/app/config.php
<project-root>/.env
Missing paths and configuration files that do not return an array are ignored.
Loading Configuration
Configuration can also be loaded directly:
use Puff\Config\Config; $basePath = __DIR__; $config = Config::load( $basePath, $basePath . '/config', $basePath . '/app/config.php', );
Config::load() accepts files or directories. A directory is scanned recursively in stable filename order. Its config.php is merged at the top level; every other PHP file is mounted under its relative filename:
config/cache.php -> cache
config/http.server.php -> http.server
config/websocket.server.php -> websocket.server
Each component file returns only the value for its own root key. Files are merged using array_replace_recursive(), so later values replace earlier values. Numeric arrays use recursive index replacement rather than list concatenation. Files that do not return an array are ignored.
Publishing Component Configuration
Puff packages may declare configuration templates in Composer metadata:
{
"extra": {
"puff": {
"config": {
"cache.php": "config/cache.php",
"http.server.php": "config/http.server.php"
}
}
}
}
Puff's post-install-cmd and post-update-cmd call Puff\Config\ConfigPublisher::publish. Missing templates are copied into the application's config directory when a component is installed. Existing application files are never overwritten.
The loader always reads <base-path>/.env. It does not automatically load environment-specific files such as dev.php, test.php, or .env.local.
Reading and Writing Values
Use dot notation to access nested configuration:
use Puff\Config\Config; $config = new Config([ 'site' => [ 'name' => 'Puff', 'locale' => 'en', ], ]); $name = $config->get('site.name'); $fallback = $config->get('site.locale', 'en'); $exists = $config->has('site.name'); $config->set('site.enabled', true); $config->set([ 'site.locale' => 'en', 'http.workers' => 4, ]); $values = $config->all();
Writing through a scalar intermediate value is rejected instead of silently replacing existing configuration:
$config = new Config(['site' => ['name' => 'Puff']]); $config->set('site.name.short', 'P'); // Throws ConfigException
Helpers and Facade
The config() helper reads from the repository registered in the Puff container:
$name = config('site.name'); $locale = config('site.locale', 'en'); config([ 'site.enabled' => true, ]); $repository = config();
The global Config facade provides the same repository operations:
$name = Config::get('site.name'); Config::set('site.enabled', true);
Environment Overrides
Process environment variables take precedence over values from .env. Top-level keys use the same environment variable name; use a double underscore to represent each nested configuration level:
TIMEZONE=UTC HTTP__ADDR=127.0.0.1:8620 DATABASE__CONNECTIONS__MYSQL__HOST=127.0.0.1
These variables map to:
timezone
http.addr
database.connections.mysql.host
Environment overrides are applied only when the corresponding configuration key already exists. Unknown keys are ignored. Keys are converted to lowercase, while a single underscore remains part of the configuration segment.
Values preserve the type of the existing configuration value when it is a boolean, integer, or float:
// Existing configuration [ 'enabled' => false, 'workers' => 1, ] // Environment ENABLED=true WORKERS=4
The resulting values are true and 4, not strings.
Use env() to read an ordinary process environment variable:
$port = env('PUFF_PORT', 8620); $debug = env('PUFF_DEBUG', false);
The default value determines boolean, integer, and float conversion. The string null is converted to null when the default value is null.
Working with .env Files
Environment::load() parses a file without changing the current process environment:
use Puff\Config\Environment; $environment = Environment::load(__DIR__ . '/.env'); $name = $environment->get('APP_NAME');
Call apply() explicitly to write the parsed values through putenv(), $_ENV, and $_SERVER:
$effective = $environment->apply();
apply() is immutable by default: an existing process environment variable is not overwritten by a value from the file. Pass false to allow replacement:
$effective = $environment->apply(immutable: false);
The returned Environment contains the effective process environment after the operation.
Supported .env syntax includes comments, export, empty values, single- and double-quoted values, inline comments, and ${VARIABLE} expansion:
APP_NAME="Puff Framework" APP_PATH=${PROJECT_ROOT}/app APP_LITERAL='${NOT_EXPANDED}' export WORKERS=4 # inline comment
Invalid entries and unreadable environment files throw Puff\Config\ConfigException.
License
Puff Config is open-source software licensed under the MIT license.