将应用程序注入控制器

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.