Router

Routing can be used in addition to the default mechanism that associates controller/action/{parameters} with an url.
Routing works by using the @route annotation on controller methods.

Routes definition

Creation

app/controllers/ProductsController.php
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
namespace controllers;
 /**
 * Controller ProductsController
 **/
class ProductsController extends ControllerBase{

     /**
     * @route("products")
     */
     public function index(){}

}

The method Products::index() will be accessible via the url /products.

Route parameters

A route can have parameters:

app/controllers/ProductsController.php
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
namespace controllers;
 /**
 * Controller ProductsController
 **/
class ProductsController extends ControllerBase{
     ...
     /**
     * Matches products/*
     *
     * @route("products/{value}")
     */
     public function search($value){
             // $value will equal the dynamic part of the URL
             // e.g. at /products/brocolis, then $value='brocolis'
             // ...
     }
}

Route optional parameters

A route can define optional parameters, if the associated method has optional arguments:

app/controllers/ProductsController.php
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
namespace controllers;
 /**
 * Controller ProductsController
 **/
class ProductsController extends ControllerBase{
     ...
     /**
     * Matches products/all/(.*?)/(.*?)
     *
     * @route("products/all/{pageNum}/{countPerPage}")
     */
     public function list($pageNum,$countPerPage=50){
             // ...
     }
}

Route requirements

php being an untyped language, it is possible to add specifications on the variables passed in the url via the attribute requirements.

app/controllers/ProductsController.php
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
namespace controllers;
 /**
 * Controller ProductsController
 **/
class ProductsController extends ControllerBase{
     ...
     /**
     * Matches products/all/(\d+)/(\d?)
     *
     * @route("products/all/{pageNum}/{countPerPage}","requirements"=>["pageNum"=>"\d+","countPerPage"=>"\d?"])
     */
     public function list($pageNum,$countPerPage=50){
             // ...
     }
}
The defined route matches these urls:
  • products/all/1/20
  • products/all/5/
but not with that one:
  • products/all/test

Route http methods

It is possible to specify the http method or methods associated with a route:

app/controllers/ProductsController.php
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
namespace controllers;
 /**
 * Controller ProductsController
 **/
class ProductsController extends ControllerBase{

     /**
 * @route("products","methods"=>["get"])
 */
     public function index(){}

}

The methods attribute can accept several methods:
@route("testMethods","methods"=>["get","post","delete"])

It is also possible to use specific annotations @get, @post
@get("products")

Route name

It is possible to specify the name of a route, this name then facilitates access to the associated url.
If the name attribute is not specified, each route has a default name, based on the pattern controllerName_methodName.

app/controllers/ProductsController.php
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
namespace controllers;
 /**
 * Controller ProductsController
 **/
class ProductsController extends ControllerBase{

     /**
     * @route("products","name"=>"products_index")
     */
     public function index(){}

}

URL or path generation

Route names can be used to generate URLs or paths.

Linking to Pages in Twig

<a href="{{ path('products_index') }}">Products</a>

Global route

The @route annotation can be used on a controller class :

app/controllers/ProductsController.php
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
namespace controllers;
 /**
 * @route("/product")
 * Controller ProductsController
 **/
class ProductsController extends ControllerBase{

 ...
     /**
 * @route("/all")
 **/
     public function display(){}

}

In this case, the route defined on the controller is used as a prefix for all controller routes :
The generated route for the action display is /product/all

automated routes

If a global route is defined, it is possible to add all controller actions as routes (using the global prefix), by setting the automated parameter :

app/controllers/ProductsController.php
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
namespace controllers;
 /**
 * @route("/product","automated"=>true)
 * Controller ProductsController
 **/
class ProductsController extends ControllerBase{

     public function generate(){}

     public function display(){}

}

inherited routes

With the inherited attribute, it is also possible to generate the declared routes in the base classes, or to generate routes associated with base class actions if the automated attribute is set to true in the same time.

The base class:

app/controllers/ProductsBase.php
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
namespace controllers;
 /**
 * Controller ProductsBase
 **/
abstract class ProductsBase extends ControllerBase{

     /**
     *@route("(index/)?")
     **/
     public function index(){}

     /**
     *@route("sort/{name}")
     **/
     public function sortBy($name){}

}

The derived class using inherited attribute:

app/controllers/ProductsController.php
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
namespace controllers;
 /**
 * @route("/product","inherited"=>true)
 * Controller ProductsController
 **/
class ProductsController extends ProductsBase{

     public function display(){}

}
The inherited attribute defines the 2 routes contained in ProductsBase:
  • /products/(index/)?
  • /products/sort/{name}

If the automated and inherited attributes are combined, the base class actions are also added to the routes.