mnapoli/fluent-symfony
mnapoli/fluent-symfony offers a fluent, chainable PHP API for Symfony service container configuration. It lets you define services, arguments, tags, and autowiring in expressive, IDE-friendly code instead of YAML or XML, making configuration easier to read, refactor, and maintain.
composer require mnapoli/fluent-symfony. Because the project has been effectively unmaintained since 2017, pin the exact version in composer.json ("mnapoli/fluent-symfony": "dev-master#<sha>") rather than a floating constraint, so a fork or tag move can't break you silently.ContainerBuilder). The core idea is that instead of declaring services in YAML/XML you build them in PHP with a chainable API: register a class, then attach arguments, method calls, and tags on the returned definition object.bin/console debug:container <id> before and after.composer.json of the package and bin/console --version. If you're on Symfony 4+, assume incompatibility until proven otherwise (see Gotchas)..argument(...), .call(...), .tag(...). Keep each chain to a single service; splitting across statements makes diffs noisy but is fine when you need conditional config.service('other.id')) rather than a raw string; to use a container parameter, reference the parameter helper (equivalent to %kernel.debug%). Passing a plain string that looks like a service ID is the most common source of silent misconfiguration..tag('kernel.event_listener', [...]) calls. Keeping tag attributes inline with the service definition is the main day-to-day win over YAML.ContainerBuilder, then add fluent definitions on top. This works because fluent-symfony is a thin layer over Symfony DI — order of loading matters only for overrides.function (FluentContainerBuilder $c) { ... }) and call it from your kernel/extension. This keeps the fluent block testable in isolation and lets you reuse it across kernels.$container->get(Foo::class) returns an instance with the expected collaborators. This is faster and more precise than booting the full kernel.ServicesConfigurator, PhpFileLoader). Before adopting this package, check whether services: in a PHP file under config/services.php already covers your need — for anything on Symfony 4.3+, it almost certainly does, and it's maintained.autowire()/autoconfigure() chain, so every argument is manual. On modern codebases this makes definitions more verbose than native Symfony, not less.composer update on an unrelated package can pull Symfony DI versions the fluent wrapper doesn't tolerate. Lockfile discipline and a CI job that runs bin/console debug:container are worth the setup.cache:warmup), not at request time. If a service fails only in production, clear var/cache and warm up manually — that's where the actionable exception will be.bin/console debug:container <id> --show-arguments shows what the fluent chain actually produced; compare it to the original YAML definition when porting. The chain itself builds a normal Definition, so all standard Symfony DI tooling applies.$container->getDefinition($id) and use the native Symfony API on it. The fluent object is a convenience layer, not a sealed abstraction — mixing is expected and safe.setDecoratedService() on the underlying definition. Watch the decoration priority argument, which is easy to omit and causes hard-to-diagnose ordering bugs.PhpFileLoader/ServicesConfigurator docs — same mental model, current and supported. If you've inherited a codebase on it, port one service file per sprint to native PHP config; the APIs are close enough to do it mechanically.How can I help you explore Laravel packages today?