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.
Read the source, don't install it. This is TheodoEvolutionLegacyWrapperBundle — a Symfony 2-era bundle, not a Laravel package. It has no service providers, no HttpKernel equivalent in Laravel, and its composer.json almost certainly pins symfony/symfony ~2.x against PHP 5.x. It will not resolve on Laravel 10/11 (PHP 8.1+). Treat the repo as prior art.
First hour, in this order:
$_SERVER/superglobals are translated into an HttpFoundation request, and how the legacy response travels back.First use case: the routing seam. You want one domain, Laravel owning new routes, legacy owning the rest. In Laravel the direct analogue is:
// routes/web.php — registered last
Route::fallback(function (Request $request) {
return app(LegacyProxy::class)->forward($request); // Guzzle + header/cookie rewrite
});
That's the piece that ports cleanly and cheaply. Everything else in the bundle is a pattern to re-implement, not code to reuse.
1. Fallback routing, not catch-all middleware. Use Route::fallback() or an explicit ordered proxy route. A global middleware that forwards everything is harder to reason about and breaks Laravel's own error/asset routes. Keep the seam declarative and visible.
2. The seam at the proxy layer first. Nginx/Envoy routes unmatched paths to the legacy vhost; Laravel owns the rest. Same intent as the bundle's in-process dispatch, without the blast radius. Only move to application-level proxying if a second vhost or ingress route is a hard infrastructure constraint.
3. Session bridge — pick one authority. The bundle's PHPSESSID-sharing approach doesn't survive the framework jump. In a Laravel rebuild choose explicitly:
Whichever you pick, exactly one app owns session issuance. Mirror this in a LegacySessionBridge bound as a singleton in AppServiceProvider.
4. Service wrapping via the container. The bundle's "wrap legacy entry points as services" translates to: define a thin client class per legacy entry point, bind it as a singleton, inject it. Never call include/require on legacy bootstrap from application code — put it behind an interface so it's mockable and so the seam is one file you can delete later.
5. Config-driven paths. Mirror the bundle's path config with config/legacy.php reading env vars. Per-environment base URLs, cookie names, and cookie domain. This is what lets you run staging against a legacy staging vhost.
6. Cut over route families, not endpoints. Keep a table: route family → owner → traffic share → rollback lever. Roll out via the proxy layer so rollback is a config change, not a deploy.
7. Adapt responses defensively. When translating legacy output: strip leading whitespace/BOM, merge Set-Cookie without duplication, rewrite absolute URLs pointing at the legacy host, and stream rather than buffer large assets.
Framing gotcha, and the biggest one: this is filed under Laravel/PHP but is a Symfony bundle. Your day-to-day leverage is architectural reference only. If someone asks you to composer require it, the answer is no.
Unmaintained, and it's on the auth path. 0 stars, 0 dependents, no security-response process. If you ever do adopt the code, you're owning a fork — PHP 8 compatibility, Symfony API drift, CI, and patching, indefinitely. Budget quarters, not days.
In-process dispatch amplifies failures. Legacy echo before headers, stray whitespace, set_error_handler/register_shutdown_function calls in legacy bootstrap, and fatal errors all surface inside your modern request lifecycle. A legacy crash becomes a generic 500 attributed to the wrong codebase. The proxy approach eliminates this category entirely.
Session divergence is the classic symptom. User logged in on one side, anonymous on the other → intermittent 403s and logout loops. Debug by logging the cookie jar on both sides for a single correlation ID, not by reading code.
Cookie collisions are silent. Same cookie name on two paths, duplicate Set-Cookie headers, or a domain-scoping mismatch will break auth with no error. Inspect raw response headers.
PHP 8 strictness. Legacy null-coercion becomes TypeError under 8.1+. Expect a hardening pass the first time you proxy real traffic, and don't mistake these for bugs in your new code.
Asset 404 storms after any URL rewrite. Crawl before each cutover.
Observability has no hooks here. Add it yourself: request correlation IDs propagated both directions, latency broken out by route family, and a distinct legacy-error metric with a recognisable signature so on-call knows which codebase to open.
Rollback is two-dimensional. Mid-migration a rollback may need to revert routing and session state. Keep the proxy as the single rollback lever and make sure sessions don't outlive the rollback.
Extension points: there aren't any you can rely on. If you must reuse anything, copy the routing-fallback discipline and the session-bridging checklist into your own small package under your ownership — days of work, and you keep the delete path.
How can I help you explore Laravel packages today?