teknoo/bridge-phpdi-symfony
Bridges PHP-DI and Symfony, enabling Symfony applications to use PHP-DI’s dependency injection container for service definitions, autowiring, and container interoperability. Helpful for projects adopting PHP-DI or migrating DI setup while keeping Symfony conventions.
Architecture fit. teknoo/bridge-phpdi-symfony is a Symfony Bundle, not a Laravel package — that distinction should frame the whole evaluation. It solves a specific problem: running PHP-DI alongside Symfony's native DI container without subclassing the Kernel or replacing the Container. It works by hooking Symfony's compile phase: DIBridgeExtension::load() builds a BridgeBuilder, which instantiates the PHP-DI container, calls extractDefinition() on each entry, and emits matching Symfony definitions whose factory is the Bridge service. At runtime, Bridge is a private PSR-11 service that proxies unknown lookups back into PHP-DI and injects Symfony parameters into the PHP-DI context. That is a coherent design and materially lighter than the official bridge, which requires container/kernel customization. The cost is that the approach depends on Symfony's container compilation internals, so its architectural fit is "good design, narrow and brittle surface."
Integration feasibility. Mechanically straightforward: composer require teknoo/bridge-phpdi-symfony, register the bundle, populate the di_bridge config tree (definitions, import, extensions, compilation_path, enable_cache). The hard constraints are the version windows: PHP 8.4+ only (no 8.3), Symfony ^6.4.24 || ^7.4 || ^8.1, php-di/php-di ^7.1.1 and php-di/invoker ^2.2.0 (older releases use implicit nullable parameters deprecated in 8.4). Any application not already on PHP 8.4 is excluded until it upgrades, which is a real gating item, not a footnote.
Technical risk. High for a production dependency, driven by project signals rather than code quality. Two stars, zero dependents, single lead maintainer, BSD-3-Clause, and a CHANGELOG-driven release habit suggest a personal/architectural project rather than a supported product. There is CI across lowest/latest dependency sets and PHPStan max + PSR-12, which is a genuine positive, but no evidence of a broad user base stress-testing edge cases. The two-container model is the dominant design risk: service ownership becomes ambiguous, ordering is priority-based and therefore implicit, and compile-time versus runtime resolution paths differ. Failure will most likely appear as a container compilation error or a subtle wrong-instance bug after a Symfony minor upgrade, not as an obvious exception.
Key questions.
Stack fit. Only viable in a Symfony 6.4.24+/7.4/8.1 application on PHP 8.4 with an existing or planned PHP-DI usage. The realistic fit is an organization consolidating PHP-DI-based libraries or legacy services into a Symfony application, or a codebase deliberately keeping framework-agnostic service definitions. It is a poor fit for greenfield Symfony work — native autowiring and service decoration are simpler and better supported — and a non-fit for Laravel.
Migration path. Adopt incrementally, not wholesale. Start by registering the bundle with an empty di_bridge.definitions list to prove the compile/runtime plumbing is inert. Then move one bounded subsystem's definitions into di_bridge.definitions, ordered by priority. Use di_bridge.import to expose selected Symfony services as aliases inside PHP-DI, and di_bridge.extensions (implementing ExtensionInterface, referenced by service id or class name, with priority) for anything the config tree cannot express. Keep a strict rule that each service is owned by exactly one container, and encode that in a manifest or code review checklist.
Compatibility. Pin Symfony, php-di/php-di, and php-di/invoker to tested patch ranges and commit the lock file. Because the bundle hooks prepend()/load() and inspects PHP-DI internals via ContainerDefinitionTrait, treat any Symfony DI or PHP-DI bump as a change requiring a full container-compile test in CI, not a routine update. Run one job on lowest dependencies and one on latest, mirroring the upstream CI matrix, to catch both directions of breakage early.
Sequencing.
di_bridge.compilation_path and APCu caching behave in a prod-like build.di_bridge.definitions block; Symfony definitions return to native).Maintenance. Low code volume, single maintainer, CHANGELOG-driven releases. The maintenance burden shifts to the consuming team: you will be the one catching Symfony DI internal changes. Budget a recurring small allocation each Symfony minor cycle for upgrade validation. Forking is realistic given the license and size — treat that as a contingency, with a named internal owner who can read BridgeBuilder.
Support. GitHub issues only, no SLA, no vendor. With zero dependents there is no community corpus to search when something breaks, so first-line diagnosis lands on your team. Documentation is README-level plus AGENTS.md; the "How PHP-DI entries are exported into Symfony" section is the critical reference and should be required reading before adoption.
Scaling. Compile-time cost scales with the number of PHP-DI definitions exported, since each becomes a Symfony service definition and each requires extraction from the PHP-DI container. For large definition sets, measure container compilation time in CI, not just locally with a warm cache. Runtime lookups through Bridge add one indirection hop for proxied entries; di_bridge.enable_cache (APCu) mitigates definition-cache overhead but introduces a required extension and an APCu-availability dependency in every environment, including CLI.
Failure modes. Most probable: (1) container compilation failure after a Symfony minor upgrade touching prepend/load semantics; (2) cache staleness after changing PHP-DI definitions when APCu is enabled — stale or missing services at runtime; (3) definition drift between the two containers producing duplicate or shadowed services that resolve to the wrong instance; (4) parameter synchronization gaps where Symfony parameters change after PHP-DI is built; (5) unsupported PHP-DI constructs (closures, non-shared entries, factory return types) failing to export cleanly. Each needs a detection path — a kernel-boot functional test in CI plus a post-deploy smoke check covering the exported services.
Ramp-up. Moderate for a senior Symfony developer, steep for anyone else: contributors must reason about two containers, PHP-DI's definition model, Symfony's compile-phase extension points, and the priority ordering rules simultaneously. Plan a half-day knowledge transfer built around the functional test fixtures (Fixtures/Kernel.php, Fixtures/config/*.yml, di*.php), since those encode the supported patterns more reliably than the prose docs. Do not assume a broad team can maintain this without a designated owner.
How can I help you explore Laravel packages today?