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

Cascading Config Laravel Package

phanan/cascading-config

Laravel package that brings cascading configuration to your apps: split settings into layered files where environment-specific values override the defaults, keeping large configs organized and avoiding duplication across environments.

View on GitHub
Deep Wiki
Context7

Getting Started

phanan/cascading-config restores Laravel 4–style environment config folders to Laravel 5: a base config/*.php tree plus an environment-specific overlay in config/{APP_ENV}/*.php. It is a small, single-purpose package (archived, ~55 stars, no dependents), so treat it as a legacy-app convenience rather than a foundation for new work.

Minimal setup:

  1. Install it (pin the version that matches your Laravel 5.x constraint; the package predates Laravel 6+):
    composer require phanan/cascading-config
    
  2. Register the provider near the top of the providers array in config/app.php so it runs before providers that read config during register():
    'providers' => [
        Phanan\CascadingConfig\CascadingConfigServiceProvider::class,
        // ...
    ],
    
    Laravel 5.5+ auto-discovery may pick it up, but manual registration at the top is safer because provider order is otherwise not guaranteed.
  3. Set the environment in .env:
    APP_ENV=local
    
  4. Create the overlay directory and a single override, e.g. config/local/app.php:
    <?php
    return [
        'debug' => true,
        'name'  => 'My App (local)',
    ];
    
  5. Verify the cascade took effect:
    php artisan tinker
    >>> config('app.debug');   // true
    >>> app()->environment();  // "local"
    

First real use case: stop copying entire config files around for local development. Keep config/mail.php as the shared source of truth and add config/local/mail.php with only 'driver' => 'log', or config/local/database.php with a local socket/host. The base file remains the canonical schema; the overlay carries only the deltas for that environment.

Where to look first in the repo: the service provider (to understand when the merge happens relative to config loading), then the README for the exact folder convention and supported Laravel versions. Because the project is archived, read the source rather than assuming behavior.

Implementation Patterns

Base + sparse overlay. The productive pattern is: full config files in config/, minimal partial arrays in config/{env}/. Never duplicate a whole file into the overlay; that defeats the purpose and creates drift. A useful convention is to leave a one-line comment at the top of each overlay file naming the environment it targets.

Environment matrix. For a typical Laravel 5 app, keep overlays for the environments you actually boot:

config/
  app.php
  database.php
  mail.php
  local/
    app.php
    mail.php
  testing/
    database.php
    mail.php
  staging/
    app.php

local gets debug/log-mail; testing gets sqlite/in-memory and array mail; staging mirrors production but with verbose logging. Production usually needs no overlay beyond .env secrets.

Separate structural config from secrets. Use .env for credentials and host-specific secrets (DB_PASSWORD, API keys), and use the cascade for structural, array-shaped settings that environment variables express poorly: feature flag arrays, multi-connection definitions, queue topology, log stacks. This is the package's main justification over pure .env usage.

Testing overrides. config/testing/database.php with an in-memory SQLite connection and config/testing/mail.php with the array or log driver is a clean way to keep test config out of phpunit.xml and out of TestCase::setUp(). Ensure APP_ENV=testing is what PHPUnit actually boots with; otherwise the overlay silently does nothing.

Provider ordering. Any provider that reads config() in its own register() (common in packages that build bindings from config) must run after this one. Keep the cascading provider first and audit third-party providers that capture config early. If you see base values leaking into a service that should have the overlay, ordering is the usual cause.

Document the overlay contract. Because the merge is implicit, add a short section to the project README listing which keys each environment overlay is allowed to touch. This prevents the overlay from becoming a second, undocumented config system.

Keep overlays reviewable. Commit shared environment overlays (staging, testing) to version control. For per-developer local overlays, either commit harmless defaults or gitignore the folder—but make sure the folder's absence is a supported no-op (it is, in practice, a silent skip).

Gotchas and Tips

  • Archived and version-locked. The package targets Laravel 5 and is unmaintained. It will not understand Laravel 6+ config/bootstrap changes, PHP 8 edge cases, or package discovery semantics. On a modern app, do not adopt it; use .env plus a small AppServiceProvider-based overlay if you truly need per-environment arrays. On a legacy 5.x app, pin the version in composer.json and avoid composer update surprises.
  • Merge depth is the big trap. Cascading implementations typically use a top-level array_merge, which replaces nested arrays wholesale rather than deep-merging them. Overriding database.connections.mysql.host in config/local/database.php can wipe every other connection unless you redeclare the full connections block. Verify the package's merge behavior in the source before relying on partial nested overrides; if it is shallow, either restate the whole nested key or fork the provider to use array_replace_recursive.
  • config:cache interacts badly. php artisan config:cache flattens config into bootstrap/cache/config.php and bypasses the normal file-loading path. Depending on where the provider hooks in, the cascade may be applied on top of stale cached values, or skipped entirely, producing "works locally, broken in deploy" behavior. Always run php artisan config:clear before debugging, and re-run config:cache in each environment if you cache. When in doubt, disable config caching for apps that depend on this package.
  • APP_ENV defaults to production. If .env is missing or APP_ENV is unset, app()->environment() reports production, so a config/production/ overlay will be applied—often the opposite of what a developer expects on a fresh checkout. Make APP_ENV explicit in .env.example.
  • Silent no-ops. A misspelled environment folder (config/locl/) or a file named app.php.bak produces no error; the base config simply wins. Debug by checking app()->environment() and config('app.debug') in tinker, then confirm the overlay file returns an array (a syntax error in the overlay is the other common failure).
  • Provider position matters more than you think. Registering the provider late means other providers and bootstrappers may have already read base config. Put it first in config/app.php and re-test after adding new packages.
  • Don't put secrets in overlays. Environment folders are usually committed. Passwords, tokens, and per-machine hosts belong in .env; overlays should hold non-secret structure.
  • Extension points are limited but usable. The natural extension is to fork the provider and adjust (a) the merge strategy for deep merges, (b) the environment resolution (e.g., hostname-based folders for shared staging boxes), or (c) nested subdirectory support. There is no plugin API, so a fork is the realistic path if the default behavior is close but not sufficient.
  • Migration path off the package. If you later modernize, the replacement is mechanical: collapse each overlay into explicit env() calls in the base config, or move the deltas into a service provider that reads a single APP_ENV-keyed array. Doing this before a Laravel upgrade is cheaper than carrying an archived package across a major version boundary.
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.
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings