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

Zend Config Aggregator Laravel Package

zendframework/zend-config-aggregator

Zend Config Aggregator collects configuration from multiple sources—PHP arrays, ConfigProvider classes, and globals—into a single merged array. It supports caching and recursive merging, making it easy to compose modular application configuration in Zend/Laminas applications.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Laminas/Zend Framework package, but it works fine as a standalone Composer dependency inside a Laravel app when you need layered, mergeable configuration (e.g. feature flags, environment-aware settings, or plugin registries that would otherwise bloat config/).

composer require zendframework/zend-config-agregator

First place to look: the ConfigAggregator class and the bundled providers (PhpFileProvider, ArrayProvider, GlobFileProvider). A minimal first use case in a Laravel service provider:

use Zend\ConfigAggregator\ConfigAggregator;
use Zend\ConfigAggregator\PhpFileProvider;

$aggregator = new ConfigAggregator([
    new PhpFileProvider(base_path('config/features/*.php')),
    new PhpFileProvider(base_path('config/features/{env}/*.php'), app()->environment()),
]);

$features = $aggregator->getMergedConfig();

Bind that array into the container or expose it via a Feature facade. Caching is the second thing to look at — call $aggregator->getMergedConfig() once and cache via ConfigAggregator::CACHE_FILEMODE when generating the cache file.

Implementation Patterns

Layered config with glob providers. The common pattern is a base directory plus an environment overlay:

new ConfigAggregator([
    new PhpFileProvider(base_path('config/app/*.php')),
    new PhpFileProvider(base_path('config/app/'.app()->environment().'/*.php')),
]);

Providers are merged in order, later files win. This maps cleanly onto Laravel's env-specific config idea without abusing config/*.php.

Caching in production. Pass a cache file path as the third argument (or via the ConfigAggregator::CACHE_FILE option) so the aggregation work only happens on deploy. In a service provider:

$aggregator = new ConfigAggregator($providers, storage_path('framework/cache/config-aggregator.php'));
$config = $aggregator->getMergedConfig();

New in 1.2.0: set the octal file mode for that generated cache file via the ConfigAggregator::CACHE_FILEMODE option — useful when the web user and CLI user differ and you need group-readable cache files (0640) rather than the default.

$aggregator = new ConfigAggregator(
    $providers,
    storage_path('framework/cache/config-aggregator.php'),
    null,
    [ConfigAggregator::CACHE_FILEMODE => 0640]
);

Wrap in a custom provider. For anything dynamic (DB-driven settings, feature flags from a table), implement ConfigProvider and return an array from __invoke(). This keeps the aggregator's merge semantics while letting you source data however Laravel needs.

Wire into a singleton binding. Register the aggregator in a service provider with $this->app->singleton(...) and resolve the merged config once. Avoid constructing the aggregator per-request unless you're caching.

Gotchas and Tips

  • Namespacing: package 1.x uses Zend\ConfigAggregator. If you're on a newer Laminas stack elsewhere, remember it's Laminas\ConfigAggregator — don't mix imports.
  • Merge semantics are not array_merge_recursive blindly — the aggregator delegates to Zend\Stdlib\ArrayUtils::merge, which has specific rules for numeric keys (lists are appended, not replaced). Test any array-of-lists config carefully.
  • Cache invalidation is manual. There's no built-in "cache bust" on file change. Either include the cache file path in a deploy step that deletes it first, or use a cache key derived from a build hash.
  • File mode must be octal. Per the 1.2.0 release, pass 0600/0640 as octal literals, not the string "600". Writing 600 (decimal) will give you unexpected permissions. Also note the cache file is written by whatever user runs the process — on Laravel deploys that's often www-data in prod and your CI user locally, so mismatched ownership will bite you before the mode does.
  • PHP 7.3 support: 1.2.0 explicitly adds PHP 7.3 compatibility. If you're pinned to 7.3 on a legacy Laravel app, this version is safe; on 8.x it will still work but has no new features beyond 1.2.0.
  • Caching + env(): aggregation happens at boot, so any env() calls inside provider files need to happen before the cache is generated. If you change APP_ENV, clear the aggregator cache file.
  • Extension points: custom providers via ConfigProviderInterface, plus ConfigAggregator::addProvider() for appending at runtime (e.g. from a package's service provider) — handy for package-level config registration without forcing a rebuild.
  • Debugging merged output: var_export($aggregator->getMergedConfig(), true) into a scratch file is the fastest way to see what actually won the merge when a Laravel-app-adjacent config value looks wrong.
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.
jinas/dhivatar
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