I have the following DemoController
class DemoController {
public function test() {
return new Response('This is a test!');
}
}
I want to bind this controller to $app ['demo.controller']
$app ['demo.controller'] = $app->share ( function () use($app) {
return new DemoController ();
} );
Inside the DemoController i want to have the Application $app
object to work with registered services. What is the right way? Currently i am using __construct($app)
for the DemoController
and pass $app
. This looks like
$app ['demo.controller'] = $app->share ( function () use($app) {
return new DemoController ($app);
} );
What is the best-practice for that?
That is certainly one way to do it. I want to show two alternatives.
One is to get the application injected into the action method directly using a type hint:
use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
class DemoController
{
public function test(Request $request, Application $app)
{
$body = 'This is a test!';
$body .= ':'.$request->getRequestUri();
$body .= ':'.$app['foo']->bar();
return new Response($body);
}
}
The advantage of this option is that you don't actually need to register your controller as a service.
The other possibility is to inject the specific service instead of injecting the whole container:
use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
class DemoController
{
private $foo;
public function __construct(Foo $foo)
{
$this->foo = $foo;
}
public function test()
{
return new Response($this->foo->bar());
}
}
Service definition:
$app['demo.controller'] = $app->share(function ($app) {
return new DemoController($app['foo']);
});
The advantage of this option is that your controller no longer depends on silex, the container or any particular service name. This makes it more isolated, re-usable and easier to test in isolation.