如何根据用户角色对同一路由使用不同的控制器?

How to use different controllers, depending on the user role, for the same route?

我正在尝试实现多个控制器来监听一个路由 /account

有两个控制器,只有一个应该在 URL 上执行,选择取决于用户的角色。

namespace AppBundle\Controller;

use AppBundle\Entity\Role;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Routing\Annotation\Route;

/**
 * @Route("/account")
 */
abstract class DashboardController extends Controller
{
    protected $userRoles;

    public function __construct()
    {
        $this->userRoles = $this->getUser()->getRoles();
    }

    /**
     * Get all user roles
     */
    public function getRoles()
    {
        return $this->userRoles;
    }

    /**
     * Get user account type
     *
     * @return Role
     */
    public function getAccountType(): Role
    {
        $accountType = new Role();
        foreach ($this->userRoles as $role) {
            if(Role::ROLE_STUDENT == $role->getName()) {
                $accountType = $role;
            } else if(Role::ROLE_SCHOOL_REPRESENTATIVE == $role->getName()) {
                $accountType = $role;
            } else if(Role::ROLE_EMPLOYER == $role->getName()) {
                $accountType = $role;
            } else if(Role::ROLE_ADMIN == $role->getName()) {
                $accountType = $role;
            }
        }

        return $accountType;
    }
}
namespace AppBundle\Controller;

class CompanyDashboardController extends DashboardController
{

    public function __construct()
    {
        parent::__construct();
    }

    /**
     * @Route("/", name="dashboard_company_home", methods={"GET"})
     * @return Response
     */
    public function index()
    {
        return $this->render('dashboard/company/index.html.twig');
    }
}
namespace AppBundle\Controller;

class AdminDashboardController extends DashboardController
{

    public function __construct()
    {
        parent::__construct();
    }

    /**
     * @Route("/", name="dashboard_admin_home", methods={"GET"})
     * @return Response
     */
    public function index()
    {
        return $this->render('dashboard/admin/index.html.twig');
    }
}

这就是我目前所知道的。

您不能使用 "route" 声明来执行此操作,因为路由侦听器的执行优先级高于安全侦听器。两者都发生在 KernelEvents::REQUEST 事件期间,但路由出现在防火墙之前。

当解析到控制器映射的路由时,您还没有用户信息(这就是为什么您不能简单地附加另一个侦听器并将用户信息注入 Request 对象的原因,所以例如,它可以在 expression matching 的路由声明中使用。

基本上,一条路线,一个控制器。如果您想为这些用户提供不同的逻辑,您必须在进入控制器后应用它。