skigun/legacy-wrapper-bundle
A Symfony bundle that wraps legacy PHP applications in a modern Symfony layer, helping you run and integrate older codebases alongside current routing, services, and configuration. Useful for incremental migrations and gradual modernization without a full rewrite.
Architecture fit — a reference implementation, not a build dependency. The cataloguing as a "Laravel/PHP package" is inaccurate: skigun/legacy-wrapper-bundle is a Symfony bundle (TheodoEvolutionLegacyWrapperBundle), a Symfony 2-era artifact of Theodo's Evolution toolkit for wrapping legacy PHP entry points inside a modern Symfony kernel. Its mechanism is in-process sub-request dispatch: the modern app intercepts routes it does not own, bootstraps the legacy front controller, and bridges request/response and session state. That model has no first-class analogue in Laravel — no bundle system, no HttpKernel sub-request contract, no framework-blessed legacy bridge. For a TPM, the correct framing is: the package is evidence that incremental migration is viable, and a checklist for where the seams are. It is not an installable component for a Laravel roadmap.
Integration feasibility — poor as a dependency, good as prior art. Ranked options for a Laravel shop:
Technical risk — high, concentrated on the auth/session path. Zero stars, zero dependents, no visible production users, and a vintage that implies PHP 5.3–5.6 idioms and symfony/symfony ~2.x constraints. It will not install alongside Laravel 10/11 on PHP 8.1+. Beyond the install problem: no upstream to absorb PHP 8 deprecations or security patches; in-process dispatch multiplies blast radius by pulling legacy fatals, output-buffer leaks, and header collisions into the modern request lifecycle; and there are no observability hooks tying into Laravel's logging, tracing, or exception handler. The 35.17 opportunity score is consistent with "read it, don't ship it."
Key questions a TPM must get answered before funding engineering:
Stack fit — mismatch by default, so plan a re-implementation. Laravel cannot consume this bundle unmodified. The realistic mapping:
Route::fallback() (or an ordered catch-all with explicit exclusions) is the direct equivalent of the bundle's "unmatched route → dispatch legacy" behavior. This is the one concept that ports cleanly and cheaply, and it is worth writing down as team convention.PHPSESSID-style session. Options are a shared session store (Redis with a common serializer — fragile across framework versions), a signed interop token, or forced re-auth at the boundary. Prefer the signed token; it gives one authoritative issuer and a clean revocation story.Migration path — phased strangler fig, proxy seam first:
Compatibility caveats to budget for:
TypeError 500s the moment those code paths go live.register_shutdown_function, set_error_handler, and global state that conflict with Laravel's bootstrap. In-process wrapping amplifies this; the proxy approach eliminates it entirely.Sequencing recommendation: proxy seam in sprint 1, identity bridge in sprint 2, first route-family carve-out in the following sprint. Escalate to middleware-proxying — and only then to a fork — solely if the proxy is blocked by an infrastructure constraint you cannot negotiate. Publish the route inventory as the roadmap so stakeholders see the carve-out order, not just the intent.
Maintenance — the dominant, under-estimated cost. Taking this package means owning a fork: PHP 8 compatibility, Symfony API drift, security patching, CI, and release management, with no upstream to merge from and no obligation from the original author to respond to anything. A fork on the auth path is a multi-quarter liability. The proxy approach carries effectively zero package maintenance and shifts effort into configuration you already know how to run.
Support — no safety net. No community, no issue history to mine, no documented production users. Institutional knowledge will live entirely with whoever builds the seam. Require a written runbook, at least two engineers trained on it, and a stated fallback ("flip the proxy back") before go-live. This is a governance ask, not a nice-to-have.
Scaling — the legacy app is the constraint, and in-process wrapping couples you to it. Wrapping in-process forces legacy to scale on the modern app's cadence: same PHP-FPM pool, same memory ceiling, same deploy window. Legacy apps are typically stateful (local sessions, filesystem caches), which forces sticky sessions and blocks independent horizontal scaling. The proxy approach lets each tier scale on its own curve — a concrete, quantifiable operational win that belongs in the business case.
Failure modes to design for and instrument:
Set-Cookie headers, path-scoping conflicts; breaks auth silently. Assert on header shape in staging.echo before headers, stray whitespace, or a legacy error page rendered inside a Laravel response. In-process wrapping makes this the default, not the exception.Ramp-up — moderate, and routinely under-scoped. The conceptual model (route fallback, shared session, dual-run) is learnable in days. The real cost is the legacy application's undocumented behavior — expect 2–4 weeks before an engineer can confidently diagnose a cross-boundary failure. Fund onboarding explicitly, and pair it with instrumentation on both sides: request correlation, latency and error rate by route family. Teams that skip this debug from folklore and stall the migration.
Bottom line for a TPM: leverage this package as prior art and a seam checklist, not as a dependency. Fund a proxy-based seam plus a route-by-route carve-out plan, name an owner for the identity bridge, and secure a security sign-off on whichever token or session mechanism you choose. The engineering you avoid by not owning an unmaintained fork on the authentication path will comfortably exceed anything its in-process dispatch would have bought you.
How can I help you explore Laravel packages today?