Creative Commons License
This work is licensed under a
Creative Commons
Attribution-Share Alike 3.0
Unported License.

Master Symfony2 fundamentals

Be trained by SensioLabs experts (2 to 6 day sessions -- French or English).
trainings.sensiolabs.com

Symfony hosting done right

ServerGrove, outstanding support at the right price for your Symfony hosting needs.
servergrove.com

Discover the SensioLabs Support

Access to the SensioLabs Competency Center for an exclusive and tailor-made support on Symfony
sensiolabs.com

@Route and @Method

Usage

The @Route annotation maps a route pattern with a controller:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

class PostController extends Controller
{
    /**
     * @Route("/")
     */
    public function indexAction()
    {
        // ...
    }
}

The index action of the Post controller is now mapped to the / URL. This is equivalent to the following YAML configuration:

1
2
3
blog_home:
    pattern:  /
    defaults: { _controller: SensioBlogBundle:Post:index }

Like any route pattern, you can define placeholders, requirements, and default values:

1
2
3
4
5
6
/**
 * @Route("/{id}", requirements={"id" = "\d+"}, defaults={"id" = 1})
 */
public function showAction($id)
{
}

You can also define the default value for a placeholder with the PHP default value:

1
2
3
4
5
6
/**
 * @Route("/{id}", requirements={"id" = "\d+"})
 */
public function showAction($id = 1)
{
}

You can also match more than one URL by defining additional @Route annotations:

1
2
3
4
5
6
7
/**
 * @Route("/", defaults={"id" = 1})
 * @Route("/{id}")
 */
public function showAction($id)
{
}

Activation

The routes need to be imported to be active as any other routing resources (note the annotation type):

1
2
3
4
5
6
# app/config/routing.yml

# import routes from a controller class
post:
    resource: "@SensioBlogBundle/Controller/PostController.php"
    type:     annotation

You can also import a whole directory:

1
2
3
4
# import routes from a controller directory
blog:
    resource: "@SensioBlogBundle/Controller"
    type:     annotation

As for any other resource, you can "mount" the routes under a given prefix:

1
2
3
4
post:
    resource: "@SensioBlogBundle/Controller/PostController.php"
    prefix:   /blog
    type:     annotation

Route Name

A route defined with the @Route annotation is given a default name composed of the bundle name, the controller name and the action name. That would be sensio_blog_post_index for the above example;

The name attribute can be used to override this default route name:

1
2
3
4
5
6
7
/**
 * @Route("/", name="blog_home")
 */
public function indexAction()
{
    // ...
}

Route Prefix

A @Route annotation on a controller class defines a prefix for all action routes:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
/**
 * @Route("/blog")
 */
class PostController extends Controller
{
    /**
     * @Route("/{id}")
     */
    public function showAction($id)
    {
    }
}

The show action is now mapped to the /blog/{id} pattern.

Route Method

There is a shortcut @Method annotation to specify the HTTP method allowed for the route. To use it, import the Method annotation namespace:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;

/**
 * @Route("/blog")
 */
class PostController extends Controller
{
    /**
     * @Route("/edit/{id}")
     * @Method({"GET", "POST"})
     */
    public function editAction($id)
    {
    }
}

The edit action is now mapped to the /blog/edit/{id} pattern if the HTTP method used is either GET or POST.

The @Method annotation is only considered when an action is annotated with @Route.

Controller as Service

The @Route annotation on a controller class can also be used to assign the controller class to a service so that the controller resolver will instantiate the controller by fetching it from the DI container instead of calling new PostController() itself:

1
2
3
4
5
6
7
/**
 * @Route(service="my_post_controller_service")
 */
class PostController extends Controller
{
    // ...
}