我们现在已经知道路由指向AppBundle中的HelloController::indexAction()方法。还有更有趣的就是控制器方法的参数传递:

// src/AppBundle/Controller/HelloController.php
// ...
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
 
/**
 * @Route("/hello/{name}", name="hello")
 */
public function indexAction($name)
{
    // ...
}

控制器有个参数$name,对应所匹配路由的{name}参数(如果你访问/hello/ryan, 在本例中是ryan)。实际上当执行你的控制器时,Symfony在所匹配路由中匹配带参数控制器中的每个参数。所以这个{name}值被传入到$name。只需要确保占位符的名称和参数名称一样就行。

以下是更有趣的例子,这里的控制器有两个参数:

// src/AppBundle/Controller/HelloController.php
// ...
 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
 
class HelloController
{
    /**
     * @Route("/hello/{firstName}/{lastName}", name="hello")
     */
    public function indexAction($firstName, $lastName)
    {
        // ...
    }
}

将路由参数映射到控制器参数是十分容易和灵活的。在你开发时请遵循以下思路:

1. 控制器参数的顺序无关紧要

Symfony可以根据路由参数名匹配控制器方法参数。换句话说,它可以实现last_name参数与$last_name参数的匹配。控制器可以在随意排列参数的情况下正常工作。

public function indexAction($lastName, $firstName)
{
    // ...
}

2.控制器所需参数必须匹配路由参数

下面会抛出一个运行时异常(RuntimeException),因为在路由定义中没有foo参数:

public function indexAction($firstName, $lastName, $foo)
{
    // ...
}

如果参数是可选的,那该多好。下面的例子不会抛出异常:

public function indexAction($firstName, $lastName, $foo = 'bar')
{
    // ...
}

3.不是所有的路由参数都需要在控制器上有响应参数的

如果,举个例子,last_name对你控制器不是很重要的话,你可以完全忽略掉它:

public function indexAction($firstName)
{
    // ...
}

你也可以从你的路由器传入其他的参数到你的控制器参数。请看 如何从路由向控制器传递额外的信息