I found hints of this while working on refactoring a project into using MVC.
Framework Independent Controllers by Matthias Noback
Pimple Container with Yaml by Gonzalo
Symfony post about Controllers as a service
Controllers as a Service.
Using Symfony’s Routing and Resolvers, it seems like a simple move.
Well it was(n’t). I tried this tutorials, Messing Around with Silex Pimple, one issue I found was that the Silex is still using v1 of Pimple which now has changed to Pimple\Container, removed the ->share
method and just over all matured. So I needed find a way to do this outside of Silex and using a new version of Pimple’s Container.
The second part was fairly easy since ->share is now just = function($c)
since its now the default.
The first part was the issue. How do I get Symfony’s Controller Resolver to work with Pimple outside of the Symfony Framework and not in Silex.
The hunt began.
I found this file that depended on the file below it:
It also depended on the symfony ControllerResolver but that was easy to add.
<?php
use Symfony\Component\ClassLoader\MapClassLoader as MapClassLoader;
use Symfony\Component\ClassLoader\UniversalClassLoader;
use Pimple\Container;
//temporary till mvc is setup use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Config\FileLocator;
use Symfony\Component\Routing\Loader\YamlFileLoader;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing;
use Symfony\Component\HttpKernel;
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface; $container['callback_resolver'] = function ($c) {
return new \App\Component\CallbackResolver($c);
};
$container['request'] = function($c) {
return Request::createFromGlobals();
};
$container['resolver'] = function($c) {
return new \App\Component\HttpKernel\Controller\ServiceControllerResolver(new HttpKernel\Controller\ControllerResolver(), $c['callback_resolver']);
};
$container['routes'] = function($c) {
return new RouteCollection();
};
$container['routes'] = $container->extend('routes', function(RouteCollection $routes) {
$loader = new YamlFileLoader(new FileLocator(APP_DIR . '/Resource/config'));
$collection = $loader->load('routes.yml');
$routes->addCollection($collection);
return $routes;
});
$container['context'] = function($c) {
return new Routing\RequestContext();
};
$container['matcher'] = function($c) {
return new Routing\Matcher\UrlMatcher($c['routes'], $c['context']);
};
//Controller Service
$container['index_controller'] = function($c) {
return new \App\Controller\IndexController($c['database']);
};
$container['config'] = function($c) {
return;
};
$container['kernel'] = function($c) {
return new \App\Kernel($c['matcher'], $c['resolver']);
};
$container['context']->fromRequest($container['request']);
$response = $container['kernel']->handle($container['request']);
$response->send();
Modified ServiceControllerResolver File from Silex Framework
Modified CallbackResolver File From Silex Framework
There are still somethings to work out with these files so that error handling / logging is taken care of. The services will soon be loaded by a yaml file but in all it was a great fix to make the controller have dependencies and not require being built to meet the Silex/Symfony only needs.
Continue reading Building an MVC while Refactoring – Part 2 – Controllers as a Service