A silex service provider that allows the use of annotations in ServiceControllers.

v2.0.1 2018-03-20 05:18 UTC


Build Status Scrutinizer Code Quality


A Silex ServiceProvider that defines annotations that can be used in a Silex controller. Define your controllers in a class and use annotations to setup routes and define modifiers.


Install the silex-annotation-provider using composer.

    "require": {
        "ddesrosiers/silex-annotation-provider": "~2.0"


$app->register(new DDesrosiers\SilexAnnotations\AnnotationServiceProvider(), array(
    "annot.cache" => new ApcCache(),
    "annot.controllerDir" => "$srcDir/Controller",
    "annot.controllerNamespace" => "Company\\Controller\\"



Specify the directory in which to search for controllers. This directory will be searched recursively for classes with the @Controller annotation. Found controller classes will be processed for route annotations. Either this or annot.controllers is required to locate controllers. If a cache object is given using the 'annot.cache' option and the 'debug' option is true, the list of controller classes will be cached to improve performance.


The base namespace of the controllerDir. This option works with the annot.controllerDir option. It is not required, but saves the service from having to do the work of figuring out the namespace of the controller classes.


An array of fully qualified controller names. If set, the provider will automatically register each controller as a ServiceController and set up routes and modifiers based on annotations found. Controllers can be grouped into controller collections by grouping them with an associative array using the array key as the mount point.

$app['annot.controllers'] = array(


An instance of a class that implements Doctrine\Common\Cache\Cache. This is the cache that will be used by the AnnotationReader to cache annotations so they don't have to be parsed every time. Make sure to include Doctrine Cache as it is not a required dependency of this project.

annot.base_uri (Enables Faster Controller Registration)

This is the base uri of all requests. Basically, it's the part of the URI that isn't included in $_SERVER['REQUEST_URI']. If your bootstrap file is at the root of htdocs, the value is "/". If your bootstrap file lives in a directory called "api", all your API's URIs are prefixed with "/api" and that is value you must specify for annot.uri.

annot.base_uri enables faster registration of controllers. Silex has to register every endpoint in your app on every request. If you have a lot of endpoints, that could be a significant overhead on each and every request. Silex Annotations can improve this by filtering the controllers that need to be registered using the prefix on the Controller annotation. We only need to register the endpoints in the Controller if the prefix matches the URI. In this way, Silex Annotations allows FASTER routing than pure Silex.

Annotate Controllers

Create your controller. The following is an example demonstrating the use of annotations to register an endpoint.

namespace DDesrosiers\Controller;

use DDesrosiers\SilexAnnotations\Annotations as SLX;
use Symfony\Component\HttpFoundation\Response;

 * @SLX\Controller(prefix="/prefix")
 * @SLX\RequireHttps
class TestController
	 * @SLX\Route(
	 *		@SLX\Request(method="GET", uri="test/{var}"),
	 *		@SLX\Assert(variable="var", regex="\d+"),
	 *		@SLX\Convert(variable="var", callback="\DDesrosiers\Controller\TestController::converter")
	 * )
	public function testMethod($var)
		return new Response("test Method: $var");

	public static function converter($var)
		return $var;

The annotations in our TestController are interpreted as follows:

$controllerCollection = $app['controller_factory'];
$controller->get("test/{var}", "\\DDesrosiers\\Controller\\TestController:testMethod")
	->assert('var', '\d+')
	->convert('var', "\\DDesrosiers\\Controller\\TestController::converter");
$app->mount('/prefix', $controllerCollection);

Controller Providers

If we want to use a ControllerProvider, we can use the annotations service's process() method directly.

namespace DDesrosiers\Controller;

use DDesrosiers\SilexAnnotations\Annotations as SLX;
use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Response;

class TestProviderController implements ControllerProviderInterface

	function connect(Application $app)
		return $app['annot']->process(get_class($this), false, true);

	 * @SLX\Route(
	 *		@SLX\Request(method="GET", uri="test/{var}"),
	 *		@SLX\Assert(variable="var", regex="\d+"),
	 * )
	public function testMethod()
		return new Response("test Method");

The ControllerProviderInterface's connect() requirement was satisfied by calling the annotation service's process() method.


When registered, an instance of AnnotationService is available via $app['annot']; The AnnotationService's process() method parses annotations in a class to configure controllers. It is usually not necessary to use the service directly. AnnotationService->process() takes 3 arguments:

  • controllerName: The fully qualified class name of the controller to process.
  • isServiceController: This matters because Silex expects a different string representation of a controller method for ServiceControllers. Default: false.
  • newCollection: If true, all routes found will be put into a new controller collection and that collection will be returned. Default: false.

Advanced Options


Controllers are registered as service controllers by default. This option can be used to override this default.


Define your own callback to search for controllers.


This callback registers the service controller. Override it if you need to do anything special to register your controllers.



The @Controller annotation marks a class as a controller. The 'prefix' option defines the mount point for the controller collection.


The @Route annotation groups annotations into an isolated endpoint definition. This is required if you have multiple aliases for your controller method with different modifiers. All other annotations can be included as sub-annotations of @Route or stand on their own.


The @Request annotation associates a uri pattern to the controller method. If multiple @Request annotations are given, all modifiers will be applied to all @Requests unless they wrapped in a @Route annotation.

  • method: A valid Silex method (get, post, put, delete, match)
  • uri: The uri pattern.



  • variable
  • regex



  • variable
  • callback



  • host







  • variable
  • default



  • callback



  • callback



  • routeName


The Modifier annotation is a catch-all to execute any method of the Controller or Route. All methods should have an annotation, but this annotation is provided as a way to "future-proof" the annotation provider. In case something is added in the future, users can use it right away instead of waiting for a new annotation to be added.



  • method (name of the method to call on the Route object)
  • args (array of arguments to send the the method)