Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Config Laravel Package

fastd/config

Lightweight configuration component for FastD PHP applications: load and merge PHP config files, resolve environment-specific values and variables, access settings through a simple repository API, and cache parsed configuration for faster production bootstrap.

View on GitHub
Deep Wiki
Context7

Getting Started

fastd/config is the configuration component of the FastD micro-framework — a small, dependency-free container for key/value configuration that can be loaded from PHP array files and injected as a service. It is not a .env/dotenv replacement and does not ship the config() helper (that lives in fastd/framework).

Minimum steps:

composer require fastd/config
use FastD\Config\Config;

$config = new Config();
$config->load(__DIR__ . '/config/app.php'); // file must `return [...]`
$config->get('app.name', 'default');

Where to look first, in order:

  1. src/Config.php and src/ConfigInterface.php — the entire public surface is a handful of methods (load, get, set, has, merge, remove, all). Read this before anything else; it is short enough to read in one sitting.
  2. src/Loader/ — the loader contract and the built-in PHP-array loader. This is your extension seam.
  3. tests/ — for a package this small, the tests are the actual documentation of merge semantics and dot-notation behavior.
  4. The ConfigProvider / service-provider class (if present in your version) — how it registers into fastd/container / fastd/di.

First real use case: replace a hardcoded array in your bootstrap with config/app.php returning an array, load it once at the entrypoint, and register the instance in the container so controllers and services receive ConfigInterface instead of reaching for globals.

Implementation Patterns

Load order as override mechanism. The cheapest environment strategy with this package is compositional: load config/app.php, then load config/{FASTD_ENV}/*.php on top. Later loads merge over earlier ones, which gives you sane defaults plus per-environment deltas without any templating. Keep the environment name in a single bootstrap variable so the whole thing stays deterministic.

One top-level key per file. Since merges are shallow-ish and dot-get flattens namespaces, name each file's return array after the file (database.php returns ['database' => [...]]). This prevents two files from quietly clobbering each other's keys and makes var_dump($config->all()) readable when debugging.

Resolve secrets at boot, not in files. Don't commit hostnames or credentials into array files, even per-environment ones. In the bootstrap, read getenv()/$_ENV and set() the values after the file loads, or use the package's %placeholder% resolver if your version supports it. Keep the resolution in one function so you can log or assert it in one place.

Wire it as a container service, inject the interface. Register Config (or a read-only wrapper around it) as a shared service, then type-hint ConfigInterface in constructors. This is where the package actually earns its keep: services stop taking five scalar constructor arguments and take one config object, and tests can construct a config with set() only — zero filesystem I/O.

Fail fast on missing critical keys. After all loads complete, add a boot-time guard that checks the handful of keys that must exist (database.host, app.key, etc.) and throws. Configuration typos that produce null at request time are the most expensive class of bug this kind of package enables.

Test fixtures over real config. Point load() at tests/fixtures/config/ in integration tests; use bare set() for unit tests. Never let tests read the project's real config directory — it makes tests order- and environment-dependent.

Skip the caching layer. Array-returning PHP files are already opcache-friendly. Writing a serialized config cache on top adds an invalidation problem for a few milliseconds. Only consider it if you add a non-PHP loader (JSON/YAML/DB).

Gotchas and Tips

  • Adoption is essentially zero (3 stars, 0 dependents). There will be no StackOverflow answers and no third-party tutorials. Read the tests, pin an exact version in composer.json, and note that as MIT with ~a dozen files you can vendor it into src/ and own it if the maintainer goes quiet. Budget for that.
  • The PHP loader expects a file that returns an array. require on a file without a return yields 1, so you can end up with a scalar silently merged or ignored. Wrap load() in your own helper that asserts is_array() before handing it over.
  • Merge semantics on lists are the sharp edge. Lists of providers, middlewares, or routes typically get replaced, not appended, when a later layer merges over an earlier one. If you need append behavior, do it explicitly in code, and write one test per list you rely on.
  • Dot notation vs. literal keys. Any key containing a dot (hostnames, cache keys like cache.user.1) will be misread by the dot-getter. Avoid dots inside keys, or keep those values in a nested array rather than a flat string key.
  • get() on a missing key is not your safety net. Whether it returns null, false, or throws varies by method and version — always pass the default explicitly, and rely on the boot-time required-key check rather than scattered ??.
  • Shared-service state leaks in long-running workers. Under Swoole/RoadRunner or in a test suite that boots the kernel repeatedly, a shared Config instance carries mutated state between requests. Rebuild or reset it per request cycle, and make the post-boot phase read-only via a wrapper.
  • Placeholder resolution can fail quietly. Unresolved %...% placeholders often survive into runtime as literal strings. Add a debug assertion that scans all() for leftover % after resolution, at least in non-production.
  • Release dates are monorepo artifacts. The 2026-10-27 last-release date is a tag from the FastD monorepo's release train, not a signal of independent maintenance. Judge activity by the commit log on src/Config.php, not by tags.
  • Extension points worth knowing: a custom LoaderInterface implementation (JSON/TOML/DB-backed config, or a *.local.php overlay) and a custom resolver for secrets. Both are small, contained additions — this is the one place the package rewards you for reading the interfaces.
  • Debugging shortcut: right after boot, dump the file path alongside the keys it contributed (a tiny loop over your load calls). Config bugs are almost always "the wrong file loaded, or the right file loaded in the wrong order," and this makes both visible in one line of output.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core