3

I'm trying to start migrating my legacy project to Symfony, piece by piece (Strangler Application). I followed this documentation, but I can only load my home URL / of my legacy application. Other URL's will give me a 404 even before I get to the LegacyBridge class.

What do I miss?

EDIT:
Probably people don't understand my question. I have no issues starting my Symfony project. I'm trying to build a Strangler Application, slowly migrating my legacy code to Symfony. So my legacy code and Symfony application are running side by side. But everything is loaded through the frontend controller of Symfony.

So I modified the index.php from Symfony public/index.php.

I added a LegacyBridge class to the frontend controller of Symfony:

<?php
// public/index.php
use App\Kernel;
use App\LegacyBridge;
use Symfony\Component\Debug\Debug;
use Symfony\Component\HttpFoundation\Request;

require dirname(__DIR__).'/config/bootstrap.php';

/*
 * The kernel will always be available globally, allowing you to
 * access it from your existing application and through it the
 * service container. This allows for introducing new features in
 * the existing application.
 */
global $kernel;

if ($_SERVER['APP_DEBUG']) {
    umask(0000);

    Debug::enable();
}

if ($trustedProxies = $_SERVER['TRUSTED_PROXIES'] ?? $_ENV['TRUSTED_PROXIES'] ?? false) {
    Request::setTrustedProxies(explode(',', $trustedProxies), Request::HEADER_X_FORWARDED_ALL ^ Request::HEADER_X_FORWARDED_HOST);
}

if ($trustedHosts = $_SERVER['TRUSTED_HOSTS'] ?? $_ENV['TRUSTED_HOSTS'] ?? false) {
    Request::setTrustedHosts([$trustedHosts]);
}

$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);

/*
 * LegacyBridge will take care of figuring out whether to boot up the
 * existing application or to send the Symfony response back to the client.
 */
$scriptFile = LegacyBridge::prepareLegacyScript($request, $response, __DIR__);
if ($scriptFile !== null) {
    require $scriptFile;
} else {
    $response->send();
}
$kernel->terminate($request, $response);

I already get a 404 on line $response = $kernel->handle($request);.

<?php
//src/LegacyBridge.php

namespace App;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class LegacyBridge
{
    public static function prepareLegacyScript(Request $request, Response $response, string $publicDirectory)
    {

        // If Symfony successfully handled the route, you do not have to do anything.
        if (false === $response->isNotFound()) {
            return;
        }

        // Figure out how to map to the needed script file
        // from the existing application and possibly (re-)set
        // some env vars.

        $dir = $request->server->get('SERVER_NAME');
        $dir = str_replace('.test', '.nl', $dir);

        $legacyScriptFilename = realpath($publicDirectory . '/../../' . $dir . '/index.php');

        return $legacyScriptFilename;
    }
}
tereško
  • 58,060
  • 25
  • 98
  • 150
Timo002
  • 3,138
  • 4
  • 40
  • 65
  • You are maybe missing routes, defined in `/config/routes.yaml` – Cid Oct 08 '19 at 07:10
  • I have no routes yet in my new Symony application. An I suppose I don't need to add the legacy routes to the routes.yaml file. – Timo002 Oct 08 '19 at 07:17
  • `php bin/console make:controller` will generate a template and controller with a route for you. – Shamshid Oct 08 '19 at 07:22
  • @MohammedShamshid, I understand, but I want my Legacy project to run through Symfony an piece by piece convert it to Symfony. So in the basis I first need to get my Legacy running, not Symfony – Timo002 Oct 08 '19 at 07:24
  • I don't think it is possible to run legacy project in Symfony. generate controllers and move your codes piece by piece by running 2 virtual hosts. – Shamshid Oct 08 '19 at 07:29
  • @MohammedShamshid, Yes it is! See: https://symfony.com/doc/current/migration#front-controller-with-legacy-bridge – Timo002 Oct 08 '19 at 07:31
  • did you set the Legacy Route Loader? – Shamshid Oct 08 '19 at 07:38
  • please post the contents of public/index.php and your LegacyBridge class – Arleigh Hix Oct 08 '19 at 07:39
  • @MohammedShamshid, no, I want to use Front Controller with Legacy Bridge – Timo002 Oct 08 '19 at 07:51

1 Answers1

3

The 404 response should be generated on the line you mention (as expected) but not sent until the else block below:

$scriptFile = LegacyBridge::prepareLegacyScript($request, $response, __DIR__);
if ($scriptFile !== null) {
    require $scriptFile;
} else {
    $response->send();
}

Which means $scriptFile is null. So, in your LegacyBridge add the following to debug the path:

$legacyScriptFilename = realpath($publicDirectory . '/../../' . $dir . '/index.php');

// next two lines for debug
var_dump($legacyScriptFilename);
die();

return $legacyScriptFilename;

That will dump $legacyScriptFilename and kill further execution, so you can verify the if the path is correct.

If you are getting an uncaught Exception try catching and suppressing it like so:

try {
  $response = $kernel->handle($request);
} catch (\Exception $e) {
  $response = new Response(); 
  $response->setStatusCode(404);
}

That should allow execution to continue despite the Exception.

Arleigh Hix
  • 9,990
  • 1
  • 14
  • 31
  • So to be clear, I have not configured any routes in the Symfony project. First I need to get the legacy project running through the frontend controller of Symfony. If I go to `/`, the debug lines throw me the correct path that should be execouted. If I go to `/other-url`, the debug lines is not hit. Because in `public/index.php` the line above the LegacyBride `$response = $kernel->handle($request);` already throws an exception. 404 NotFoundHttpException – Timo002 Oct 08 '19 at 08:09
  • Yes: (1/2) ResoureseNotFountExeption in CompiledUrlMatcherTrait.php line 70. (2/2) NotFoundHttpException in RouteListener.php line 138 – Timo002 Oct 08 '19 at 08:24
  • @Timo002 updated my answer, if that doesn't work something must be wrong with the kernel or (?) – Arleigh Hix Oct 08 '19 at 08:44
  • Hmm, understand what you are trying, now my `$response` is empty. So the LegacyBridge, which expects a `Response` object is complaining. Undefined variable – Timo002 Oct 08 '19 at 08:49
  • Ooh, in the catch, I created an empty Response and set the status to 404. $response = new Response(); $response->setStatusCode(404); This seems to do the trick! – Timo002 Oct 08 '19 at 08:52
  • Ok, sorry my ISP was down for a bit, I'll update the catch with what you did – Arleigh Hix Oct 08 '19 at 09:34