How to use the Symfony 2 Container in a legacy app

2019-03-19 18:57发布

Would like to integrate a legacy application with a Symfony 2 application - replacing more and more parts of the old application with Symfony components. The approach I would take is using the Symfony 2 container in the legacy application getting the services that are already configured for the Symfony 2 application. The first services I would like to use are the session and the security context.

Questions:

  • Is this feasible?
  • How do I get the configured service container?

More info in the legacy application: The typical PHP mess: Single PHP files, as "controllers" (checking $_GET and $_POST for different execution paths). Each page includes init.php which sets up autoloading, database connection etc. The session management has its own class (which i would like to replace), the data is retrieved through calls to static methods (!) of database objects.

2条回答
我命由我不由天
2楼-- · 2019-03-19 19:41

Using Symfony's DIC as a standalone component is possible but you'd have to do many things "manually" (as you're not planning on using full Symfony Framework from the very beginning). You'll probably won't get much of using DIC with all that legacy stuff.

If you want to go this path I'd consider choosing another component first (like HttpFoundation and HttpKernel).

As @Cerad suggested you might wrap your legacy code in Symfony. Have a look at IngewikkeldWrapperBundle bundle. You can't use it as is but it might give you some ideas.

There's a third way.

You can decide to implement every new feature in a Symfony app. Than, you can make that both legacy and Symfony apps coexist. On a server level (i.e. Nginx), you might proxy legacy URLs to the legacy app and all the migrated URLs to a Symfony2 app. In my case this scenario was the best option and proved to be working. However, we were committed to abandon legacy app development (so every new feature or change had to be developed in a Symfony2 app).

Edit: here's how you could boot the Symfony kernel in a legacy app and dispatch an event (which is needed for the firewall):

$kernel = new \AppKernel('dev', true);
$kernel->boot();

$request = Request::createFromGlobals();
$request->attributes->set('is_legacy', true);
$request->server->set('SCRIPT_FILENAME', 'app.php');

$container = $kernel->getContainer();
$container->enterScope('request');
$container->get('request_stack')->push($request);
$container->set('request', $request);

$event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
$eventDispatcher = $container->get('event_dispatcher');
$eventDispatcher->dispatch('kernel.request', $event);
查看更多
在下西门庆
3楼-- · 2019-03-19 19:41

I believe you can access the container instance from your legacy application like this

$kernel = new AppKernel('prod', true);
$kernel->loadClassCache();
$kernel->boot();
$request = Request::createFromGlobals();
$container = $kernel->getContainer();
$sc = $container->get('security.context');
查看更多
登录 后发表回答