Search code examples
phpsymfonysymfony5

How to define complex regular expressions once and reuse them in multiple routes


In my Symfony5.1 application, there are a lot of routes using regular expression like this one:

    /**
     * @Route("/foo/{page<^[1-9][0-9]*$>}", name="foo", methods="GET")
     */
    public function list(int $page = 1): Response
    {
        // ...
    }

The route documentation said that it's possible to use container parameter:

Route requirements (and route paths too) can include container parameters, which is useful to define complex regular expressions once and reuse them in multiple routes.

I created a parameter in the services.yaml file:

    parameters:
        page: '<^[1-9][0-9]*$>'

But how do I call the above parameter in my route annotation?

I tried without success:

  • @Route("/foo/{page<page>}", name="foo", methods="GET")
  • @Route("/foo/{page}", name="foo", methods="GET", requirements=env:page)
  • @Route("/foo/{page}", name="foo", methods="GET", requirements={"page"=page})
  • @Route("/foo/{page}", name="foo", methods="GET", requirements={"page"=parameter:page})
  • @Route("/dogs/{page<%env(page)%>}", name="dogs", methods="GET")
  • @Route("/foo/{page}", name="foo", methods="GET", requirements={"page"=%env(page)%})

The two last ones aren't returning a 404 error but: Using "%env(page)%" is not allowed in routing configuration.

How to call my parameter in the route annotation?


Solution

  • Your Controller:

        /**
         * @Route("/foo/{page<%page%>}", name="foo", methods="GET")
         */
        public function list(int $page = 1): Response
        {
            // ...
        }
    

    parameters.yaml

    parameters:
      page: '^[1-9][0-9]*$' # Without `<` and `>`