Skip to content
Advertisement

Overriding Symfony Controller Methods doesn’t work properly

I am trying to create a new controller function in the overridden controller class but it doesn’t work as intended.

I have a common bundle where I use it for many clients. When sometimes when a client needs a specific function I creates an override for the common controller in the client bundle.

Here is my code for the common bundle controller.

class FrontController extends Controller
{
   // This is the controller in my common bundle

   /**
    * @Route("/foo/{id}", name="front_view")
    */
   public function viewAction(
       string $id,
       Request $request
   ){
       // My Controller code
   }
}

Here is my overridden controller code for client bundle.

class ClientFrontController extends FrontController
{
   // I have 2 controller methods in this class

  // First method overrides the FrontController's viewAction method
  // This works fine
  /**
    * @Route("/foo/{id}", name="front_view")
    */
   public function viewAction(
       string $id,
       Request $request
   ){
       // My Controller code
   }

  //Second method
  //This is the problem
  /**
    * @Route("/foo/bar", name="foo_bar")
    */
   public function fooBarAction(
       Request $request
   ){
       // My Controller code
   }
}

The problem I am facing is that when I navigate to /foo/bar route, it goes to /foo/{id} the overridden method in ClientFrontController.

Why is this happening? How can I make both routes work?

Advertisement

Answer

Routes order is relevant.

/foo/bar is included within /foo/{id}. When evaluating the request, /foo/bar matches /foo/{id} (with id being bar) and since it’s declared/read earlier, front_view handles the request.

If you are on Symfony < 5.1, try moving the routes around (so that foo_bar comes earlier than front_view). Or even changing the routes so that there is no overlap.

If you are on Symfony 5.1+, you can now use priority on route annotations/attributes. Read the announcement here, and the docs here.

class ClientFrontController extends FrontController
{

   /**
    * @Route("/foo/{id}", name="front_view")
    */
   public function viewAction(string $id, Request $request)
   {
       // My Controller code
   }

   /**
    * @Route("/foo/bar", priority=10, name="foo_bar")
    */
   public function fooBarAction(Request $request)
   {
       // My Controller code
   }
}
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement