Contributed by
Nicolas Grekas
in #26518.

Symfony 路由组件 允许对使用了 requirementsdefaults 选项的路由占位符去定义各自的 requirements(条件)default values(默认值)

例如,下面的使用 PHP annotations 定义的路由,page 占位符被限制为只能接受整数并且它的默认值是 1:

1
2
3
4
5
6
7
8
9
10
11
12
use Symfony\Component\Routing\Annotation\Route;
 
class BlogController extends Controller
{
    /**
     * @Route("/blog/{page}", name="blog_list", requirements={"page"="\d+"}, defaults={"page"="1"})
     */
    public function list($page)
    {
        // ...
    }
}

对于简单条件来说,这样的路由配置略显冗长。这就是为何在 Symfony 4.1 中你可以在占位符的 行内完成路由的 requirements 和 default values 配置。前例若在 Symfony 4.1 中会是下面这样:

1
2
3
4
5
6
7
/**
 * @Route("/blog/{page<\d+>?1}", name="blog_list")
 */
public function list($page)
{
    // ...
}

新语法是 {placeholder-name<requirements>?defaults},它的每个部分都是可选的,而且可以工作在所有配置格式中 (annotations, YAML 以及 XML):

1
2
3
4
5
6
7
8
9
10
11
blog_list:
    # no requirements and no default value / 无条件,无默认值
    path: /blog/{page}
    # with requirements but no default value / 有条件,无默认值
    path: /blog/{page<\d+>}
    # no requirements but with a default value / 无条件,有默认值
    path: /blog/{page?1}
    # no requirements but with default value = null / 无条件,默认值是null
    path: /blog/{page?}
    # with requirements and default value = null / 有条件,默认值是null
    path: /blog/{page<.*>?}

在同一路由中你可配置多个占位符,但如果占位符数量过大或条件过于复杂时,会导致路由配置的可读性降低,也许你应该退回到前述语法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// this config may be too complex to inline it:
// 这种配置在行内过于复杂化
 
/** @Route("/{_locale<en|es|fr>?en}/blog/{category<news|releases|security>?news}/{page<\d+>?1}", name="blog_list") */
public function list($page) { }
 
// in this case it may be better to keep using the traditional syntax
// 此时就要继续使用传的统路由语法
 
/**
 * @Route("/{_locale}/blog/{category}/{page}", name="blog_list",
 *   "requirements"={"_locale": "en|es|fr", "category": "news|releases|security", "page": "\d"},
 *   "defaults"={"_locale": "en", "category": "news", "page": "1"}
 * )
 */
public function list($page) { }