RSS Git Download  Clone
Raw View History
Blames found: 1 Mode: rst Binary: false


Hang on, we reloading big blames...
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 these rules in mind: * Overriding existing services must occur **after** the provider is registered. *Reason: If the service already exists, the provider will overwrite it.* * You can set parameters any time **after** the provider is registered, but **before** the service is accessed. *Reason: Providers can set default values for parameters. Just like with services, the provider will overwrite existing values.* Included providers ~~~~~~~~~~~~~~~~~~ There are a few providers that you get out of the box. All of these are within the ``Silex\Provider`` namespace: * :doc:`AssetServiceProvider <providers/asset>` * :doc:`CsrfServiceProvider <providers/csrf>` * :doc:`DoctrineServiceProvider <providers/doctrine>` * :doc:`FormServiceProvider <providers/form>` * :doc:`HttpCacheServiceProvider <providers/http_cache>` * :doc:`HttpFragmentServiceProvider <providers/http_fragment>` * :doc:`LocaleServiceProvider <providers/locale>` * :doc:`MonologServiceProvider <providers/monolog>` * :doc:`RememberMeServiceProvider <providers/remember_me>` * :doc:`SecurityServiceProvider <providers/security>` * :doc:`SerializerServiceProvider <providers/serializer>` * :doc:`ServiceControllerServiceProvider <providers/service_controller>` * :doc:`SessionServiceProvider <providers/session>` * :doc:`SwiftmailerServiceProvider <providers/swiftmailer>` * :doc:`TranslationServiceProvider <providers/translation>` * :doc:`TwigServiceProvider <providers/twig>` * :doc:`ValidatorServiceProvider <providers/validator>` * :doc:`VarDumperServiceProvider <providers/var_dumper>` .. note:: The Silex core team maintains a `WebProfiler <https://github.com/silexphp/Silex-WebProfiler>`_ provider that helps debug code in the development environment thanks to the Symfony web debug toolbar and the Symfony profiler. Third party providers ~~~~~~~~~~~~~~~~~~~~~ Some service providers are developed by the community. Those third-party providers are listed on `Silex' repository wiki <https://github.com/silexphp/Silex/wiki/Third-Party-ServiceProviders-for-Silex-2.x>`_. You are encouraged to share yours. Creating a provider ~~~~~~~~~~~~~~~~~~~ Providers must implement the ``Pimple\ServiceProviderInterface``:: interface ServiceProviderInterface { public function register(Container $container); } This is very straight forward, just create a new class that implements the register method. In the ``register()`` method, you can define services on the application which then may make use of other services and parameters. .. tip:: The ``Pimple\ServiceProviderInterface`` belongs to the Pimple package, so take care to only use the API of ``Pimple\Container`` within your ``register`` method. Not only is this a good practice due to the way Pimple and Silex work, but may allow your provider to be used outside of Silex. Optionally, your service provider can implement the ``Silex\Api\BootableProviderInterface``. A bootable provider must implement the ``boot()`` method, with which you can configure the application, just before it handles a request:: interface BootableProviderInterface { function boot(Application $app); } Another optional interface, is the ``Silex\Api\EventListenerProviderInterface``. This interface contains the ``subscribe()`` method, which allows your provider to subscribe event listener with Silex's EventDispatcher, just before it handles a request:: interface EventListenerProviderInterface { function subscribe(Container $app, EventDispatcherInterface $dispatcher); } Here is an example of such a provider:: namespace Acme; use Pimple\Container; use Pimple\ServiceProviderInterface; use Silex\Application; use Silex\Api\BootableProviderInterface; use Silex\Api\EventListenerProviderInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; class HelloServiceProvider implements ServiceProviderInterface, BootableProviderInterface, EventListenerProviderInterface { public function register(Container $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) { // do something } public function subscribe(Container $app, EventDispatcherInterface $dispatcher) { $dispatcher->addListener(KernelEvents::REQUEST, function(FilterResponseEvent $event) use ($app) { // do something }); } } 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:: use Symfony\Component\HttpFoundation\Request; $app = new Silex\Application(); $app->register(new Acme\HelloServiceProvider(), array( 'hello.default_name' => 'Igor', )); $app->get('/hello', function (Request $request) use ($app) { $name = $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``. .. _controller-providers: Controller 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\Api\ControllerProviderInterface``:: interface ControllerProviderInterface { public function connect(Application $app); } Here is an example of such a provider:: namespace Acme; use Silex\Application; use Silex\Api\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 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.