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

Dictionary Bundle Laravel Package

knplabs/dictionary-bundle

KnpDictionaryBundle lets you group tagged services into named dictionaries and fetch them by key at runtime, instead of wiring each dependency individually. Great for plugin-style architectures, handler registries, and any collection of services you want to look up dynamically without boilerplate co...

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. Low, unchanged. knplabs/dictionary-bundle remains a Symfony bundle, not a framework-agnostic library, and v3.6.0 makes that more true rather than less: the headline feature, named dictionary autowiring (PR #370), is delivered entirely through Symfony's DI autowiring/alias machinery — named service aliases resolved by parameter type + name. That is the single clearest illustration of the ceiling here. Laravel has no named-autowiring analog; its contextual binding ($this->app->when(...)->needs(...)->give(...)) covers a different problem shape, and you would not build a registry feature around it. The rest of the surface is unchanged: compiler passes and DI tags (DependencyInjection/), Form types (Form/), Validator constraints (Validator/), Twig extensions (Templating/), Faker providers (Faker/), and a web-profiler collector (DataCollector/). None have a Laravel consumer. The estimate holds: roughly 60–70% of the integration layer is inert in a Laravel application, and v3.6.0 grew the inert part, not the portable part.

What is portable is still the core: Dictionary/ — named dictionary implementations (callable-backed, iterator-backed, static), a Collection registry, wrappers, and a Factory alias. That remains a thin, in-memory value-object layer over configuration, reproducible in a service provider plus a config file in a few hundred lines, using native backed enums for the common case. One genuine improvement on this axis: PR #371 "docs: document custom dictionary implementation" now publishes the Dictionary interface as a supported extension point, which is exactly the seam an extraction needs and previously had to be inferred from source. That moves path 1 from "archaeology" toward "documented contract."

Integration feasibility. Feasible only as a reference architecture, not as an installed dependency — unchanged. The realistic paths remain:

  1. Extract the pure-PHP core (Dictionary/ namespaces) and re-implement the adapters as a Laravel service provider, a Rule::in()-style validation rule, and a Blade directive/component. Slightly de-risked by the new custom-dictionary docs.
  2. Reimplement from scratch using Laravel idioms and PHP 8.1+ backed enums.

Path 2 is still likely cheaper for the common case. The extraction friction is structural rather than documentary: the legacy nested PSR-4 layout (src/Knp/DictionaryBundle/ rather than src/) still forces namespace re-mapping and re-pointing of the PHPSpec tree, and specs still depend on a local Prophecy extension and a custom shouldBeOneOf matcher (spec/PHPSpec/).

Technical risk.

  • Framework lock-in (high, slightly increased). Named dictionary autowiring is a Symfony-DI-native feature with no Laravel equivalent. It is also a pull signal — it is the kind of capability a team would want, and the only way to get it here is to copy the bundle's wiring patterns, which is the failure mode this assessment exists to prevent.
  • Zero downstream validation (high, unchanged and unverified). v3.6.0 ships no evidence of production consumers; the release note set is dev-dependency bumps plus maintainer-authored features. Reconcile the dependent count against Packagist before citing it in any decision record — the release notes are silent on it, so this assessment cannot confirm or refute the prior "0 dependents" figure.
  • Legacy structural signals (medium, downgraded). This was previously read as a proxy for slow framework response. v3.6.0 argues against that: CI opened for Symfony 7.1 (#289), PHP 8.4 and 8.5 support (#372), and the dev toolchain was carried through two major-version jumps (PHPStan 1.10→2.1.27, Rector 1.0→2.1.7, php-cs-fixer 3.49→3.58+, Prophecy 1.18→1.19, code-coverage 6.3→6.5). That is an actively modernized project. Keep the nested-layout note as an extraction cost, and drop it as an upgrade-pace signal.
  • Fragile internal ordering (medium, unchanged). The container-compile-time ordering constraint still applies to the Symfony DI layer, and named autowiring adds another ordering-sensitive surface. This risk evaporates entirely if the DI layer is discarded — which remains the plan.
  • Silent no-op tags (medium, unchanged). Still a documented silent-failure pattern. The new AGENTS guidance (see below) is the mitigating control, and it is a control we do not inherit if we fork.
  • Lazy contract footgun (medium, unchanged). Callable- and iterator-backed dictionaries remain lazy until first value access. Any adapter that iterates eagerly — validation rule construction, Blade list rendering, API serializers — silently converts lazy lookups into eager I/O.
  • Metadata reliability (low/verify, unchanged). The stated last release date should be reconciled against the actual tag list before citation. v3.6.0 raises the version but not the confidence in the surrounding metadata.

Key questions. The prior five stand, plus one new. (1) What does composer.json actually require — is Dictionary/ free of symfony/* imports, and what is the PHP floor? (2) Do the PHPSpec suites for Dictionary/ run standalone without the bundle kernel? (3) Is the Collection/Factory alias genuinely the only public API, or do adapters reach into internals? (4) Are any dictionaries in our domain DB- or API-backed, which the bundle does not address? (5) Who owns a fork if we extract, and what is the sync cadence? (6) Does the newly documented custom-dictionary contract cover the Dictionary interface alone, or does it assume the named-autowiring registration path — i.e. does the documentation describe a seam we can reuse, or a Symfony-shaped seam we must re-cut?

Integration Approach

Stack fit. Do not install the bundle. Treat it as a specification for a Laravel-native dictionary registry. v3.6.0 does not change the mapping, and the one new feature has no row worth adding — which is itself the finding:

Bundle surface Laravel replacement
knp_dictionary.dictionaries config config/dictionaries.php
Dictionary\Collection (public) Singleton bound in a service provider, exposed via facade
Dictionary\Factory alias Container binding / factory method
Named dictionary autowiring (v3.6.0) No analog — omit. Contextual binding if ever genuinely needed
Form/ types Blade component + old()/request validation
Validator/ constraints Custom rule or Rule::in()
Templating/ Twig Blade directive @dictionary('gender') or component
Faker/ provider Faker addProvider()
DataCollector/ Omit (Telescope watcher if genuinely needed)

Migration path. Unchanged. (1) Freeze current static arrays/constants into config/dictionaries.php, preserving the bundle's {name: {values: [...], ...}} shape. (2) Register a DictionaryServiceProvider binding a collection singleton, with config:cache compatibility as a hard requirement. (3) Introduce a Dictionary facade and a dictionary() helper. (4) Add the validation rule and Blade surface. (5) Delete the hardcoded literals. Prefer PHP backed enums plus Rule::enum() for the common case; reserve the registry for dictionaries that are dynamic, localized, or shared across services. The named-autowiring feature is explicitly not part of the migration — if a developer asks for it during the build, that is the moment to re-read this assessment rather than extend scope.

Compatibility. Extracting the core still sidesteps the bundle's symfony/* constraint graph, which remains the main compatibility liability. v3.6.0 improves the upstream posture — Symfony 7.1 CI, PHP 8.4/8.5 support — but that improvement accrues to Symfony users, not to us; it does not lower the PHP floor that matters to a Laravel runtime. Verify PHP floor against our runtime, and check whether Dictionary/ implementations depend on symfony/options-resolver, symfony/config, or PropertyAccess. If they do, extraction is a rewrite, not a port, and should be scoped accordingly. Note that the dev-toolchain majors (PHPStan 2.x, Rector 2.x) are dev-only and carry no runtime constraint.

Sequencing.

  1. Spike (1–2 days): read composer.json, attempt standalone autoload of Dictionary/, run vendor/bin/phpspec run against the core specs only. Add: read the new custom-dictionary documentation (PR #371) and the AGENTS guidance (PR #368) as primary inputs — they are the most current description of the extension points and will shorten the spike. Output: go/no-go on extraction.
  2. Decision gate: extract-and-adapt vs. clean-room reimplementation vs. native enums only.
  3. Build (3–5 days): provider, config, facade, validation rule, Blade surface. Ship behind a feature flag.
  4. Pilot: migrate one dictionary (gender) end to end; measure config-cache boot impact.
  5. Rollout: migrate remaining dictionaries, then remove literals.
  6. Document: publish the lazy-contract rule — never iterate a dictionary at boot.

Operational Impact

Maintenance. The contributor process remains unusually disciplined — behavior changes require a matching PHPSpec example, and PHPSpec/PHPStan/PHP-CS-Fixer/Rector/Twig-lint gates run in CI. v3.6.0 adds a codified AGENTS.md covering bundle and spec guidance (#368), which is a meaningful maturity signal: agent-facing in-repo guidance is usually written by people who expect contributors to act without a maintainer in the loop. It also means a divergent fork is expensive to keep in sync — every upstream behavior change arrives with a spec and now with authoring conventions we must reconcile. That calculus is unchanged by this release and slightly reinforced by it. Net: still adopt neither the code nor the fork obligation. A clean-room Laravel implementation remains near-zero ongoing cost.

Support. Still no commercial support; issues and PRs are community-only. Two developments worth recording. First, a new contributor (@ErwannRousseau) authored the entire substantive half of this release — AGENTS docs, PHPStan/Symfony compatibility fix, named autowiring, custom-dictionary docs, and PHP 8.4/8.5 support. That is a bus-factor improvement versus the prior read, but it is one release deep; treat it as an encouraging trend, not an established second maintainer. Second, the documentation gap is narrowing: the README-plus-AGENTS situation is now closer to README-plus-AGENTS-plus-custom-dictionary-guide, which reduces onboarding cost for anyone reading the package as a reference. Internal support burden for the Laravel adapter remains on whoever writes it.

Scaling. Runtime cost is negligible and unchanged: dictionaries are configuration, resolved at container/config-cache time, held in memory, lazily materialized on first access. The lazy contract remains the scaling mechanism. The scaling risk remains entirely self-inflicted — any adapter that eagerly enumerates values converts a lazy dictionary into per-request I/O. Enforce with a code review rule and a boot-time timing assertion. Dictionaries backed by DB or external APIs remain out of scope for the bundle and require our own caching layer.

Failure modes.

  • Framework mismatch — attempting to register the bundle in Laravel; fails at install/autoload, not at runtime. Fast, cheap, embarrassing.
  • Named-autowiring envy (new) — a developer sees PR #370, wants named dictionary resolution, and starts copying Symfony DI patterns into the Laravel build. Fails slowly and architecturally rather than loudly.
  • Eager materialization — silent performance regression, no exception thrown, visible only under load or via profiling.
  • Unconsumed DI tags — a documented tag with no consuming compiler pass silently does nothing. Irrelevant once we discard DI.
  • Namespace/autoload breakage — the nested src/Knp/DictionaryBundle layout makes careless extraction produce class-not-found errors at runtime rather than build time.
  • Config cache staleness — dictionaries defined at runtime (not in config/) survive config:cache invisibly in some workers and not others; enforce config-only definitions.
  • Divergence drift — fork silently diverging from upstream security or PHP-version fixes. v3.6.0 makes this marginally more acute: the project is now shipping PHP 8.4/8.5 and Symfony 7.1 compatibility, so a fork starts its life already behind a moving, actively maintained target.

Ramp-up. A Symfony-fluent engineer needs roughly a day to read Dictionary/, Configuration.php, and the compiler passes and form an opinion; the new custom-dictionary docs and AGENTS file shave the better part of half a day off that. A Laravel-only engineer needs two to three days, most of which is spent learning Symfony idioms in order to justify discarding them — unchanged, and the named-autowiring feature adds a small amount of surface that must be understood and then explicitly rejected. Budget the spike as evaluation time, not implementation time — the expected outcome is a design document for a ~300-line Laravel registry, plus a decision to use native enums wherever they suffice. Against an opportunity score of 20 and an unverified dependent count, the correct TPM posture is unchanged: read it, don't depend on it. v3.6.0 is a healthy release for a package we should still not install — the modernization is real, the Symfony coupling is deeper, and neither fact moves the recommendation.

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.
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
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect