Providers

Providers allow the developer to reuse parts of an application into another one. Silex provides two types of providers defined by two interfaces: ServiceProviderInterface for services and ControllerProviderInterface for controllers.

Service Providers

Loading providers

In order to load and use a service provider, you must register it on the application:

$app = new Silex\Application();

$app->register(new Acme\DatabaseServiceProvider());

You can also provide some parameters as a second argument. These will be set after the provider is registered, but before it is booted:

$app->register(new Acme\DatabaseServiceProvider(), array(
    'database.dsn'      => 'mysql:host=localhost;dbname=myapp',
    'database.user'     => 'root',
    'database.password' => 'secret_root_password',
));

Conventions

You need to watch out in what order you do certain things when interacting with providers. Just keep to these rules:

  • Overriding existing services must occur after the provider is registered.

    Reason: If the services already exist, the provider will overwrite it.

  • You can set parameters any time before the service is accessed.

Make sure to stick to this behavior when creating your own providers.

Third party providers

Some service providers are developed by the community. Those third-party providers are listed on Silex’ repository wiki.

You are encouraged to share yours.

Creating a provider

Providers must implement the Silex\ServiceProviderInterface:

interface ServiceProviderInterface
{
    function register(Application $app);

    function boot(Application $app);
}

This is very straight forward, just create a new class that implements the two methods. In the register() method, you can define services on the application which then may make use of other services and parameters. In the boot() method, you can configure the application, just before it handles a request.

Here is an example of such a provider:

namespace Acme;

use Silex\Application;
use Silex\ServiceProviderInterface;

class HelloServiceProvider implements ServiceProviderInterface
{
    public function register(Application $app)
    {
        $app['hello'] = $app->protect(function ($name) use ($app) {
            $default = $app['hello.default_name'] ? $app['hello.default_name'] : '';
            $name = $name ?: $default;

            return 'Hello '.$app->escape($name);
        });
    }

    public function boot(Application $app)
    {
    }
}

This class provides a hello service which is a protected closure. It takes a name argument and will return hello.default_name if no name is given. If the default is also missing, it will use an empty string.

You can now use this provider as follows:

$app = new Silex\Application();

$app->register(new Acme\HelloServiceProvider(), array(
    'hello.default_name' => 'Igor',
));

$app->get('/hello', function () use ($app) {
    $name = $app['request']->get('name');

    return $app['hello']($name);
});

In this example we are getting the name parameter from the query string, so the request path would have to be /hello?name=Fabien.

Controllers providers

Loading providers

In order to load and use a controller provider, you must “mount” its controllers under a path:

$app = new Silex\Application();

$app->mount('/blog', new Acme\BlogControllerProvider());

All controllers defined by the provider will now be available under the /blog path.

Creating a provider

Providers must implement the Silex\ControllerProviderInterface:

interface ControllerProviderInterface
{
    function connect(Application $app);
}

Here is an example of such a provider:

namespace Acme;

use Silex\Application;
use Silex\ControllerProviderInterface;

class HelloControllerProvider implements ControllerProviderInterface
{
    public function connect(Application $app)
    {
        // creates a new controller based on the default route
        $controllers = $app['controllers_factory'];

        $controllers->get('/', function (Application $app) {
            return $app->redirect('/hello');
        });

        return $controllers;
    }
}

The connect method must return an instance of ControllerCollection. ControllerCollection is the class where all controller related methods are defined (like get, post, match, ...).

Tip

The Application class acts in fact as a proxy for these methods.

You can now use this provider as follows:

$app = new Silex\Application();

$app->mount('/blog', new Acme\HelloControllerProvider());

In this example, the /blog/ path now references the controller defined in the provider.

Tip

You can also define a provider that implements both the service and the controller provider interface and package in the same class the services needed to make your controllers work.

Project Versions

Table Of Contents

Previous topic

Services

Next topic

Testing

This Page