2.2Symfony路由(Routing)之参数(Parameter)

路由参数

路由的参数必须唯一,可以是ID,也可以是文章的标题,同样还可以是slug。

@Route("/blog/{slug}", name="blog_show")

路由分组和前缀

/**
 * @Route("/blog", requirements={"_locale": "en|es|fr"}, name="blog_")
 */
class BlogController extends AbstractController
{
    //
}

参数自动转换

一个常见的路由需求是将存储在某个参数中的值(例如作为用户 ID 的整数)转换为另一个值(例如代表用户的对象)。“参数转换器”会自动使用请求参数(slug)发出数据库请求以查找对象。如果没有找到对象,Symfony 会自动生成 404 响应。

/**
 * @Route("/blog/{slug}", name="blog_show")
 */
public function show(BlogPost $post): Response
{
    // $post is the object whose slug matches the routing parameter

    // ...
}

参数验证

假设您的应用程序有一个blog_show路由: /blog/{slug}和一个blog_list路由:/blog/{page}。鉴于路由参数接受任何值,因此无法区分两条路由。

//在这个例子中,\d+是一个匹配任意长度数字的正则表达式。
@Route("/blog/{page}", name="blog_list", requirements={"page"="\d+"})
@Route("/blog/{slug}", name="blog_show")
网址路由名称参数
/blog/2blog_list$page = 2
/blog/my-first-postblog_show$slug = my-first-post

路由优先级

//未定义的优先级参数priority为0
@Route("/blog/{slug}", name="blog_show")
//优先级为参数priority为2
@Route("/blog/list", name="blog_list", priority=2)

可选参数

在前面的示例中,blog_list/blog/{page}。如果用户访问/blog/1,它将匹配。但是如果他们访问/blog,它将不匹配。一旦向路由添加参数,它就必须有一个值。

//方法一(为参数添加默认值)
/**
  * @Route("/blog/{page}", name="blog_list", requirements={"page"="\d+"})
  */
 public function list(int $page = 1): Response
 {
     // ...
 }
//方法二({parameter_name?default_value},?后面如果没有值,默认值那就为null,实体类int $page需改为?int $page)
class BlogController extends AbstractController
{
    /**
     * @Route("/blog/{page<\d+>?1}", name="blog_list")
     */
    public function list(int $page): Response
    {
        // ...
    }
}

可以有多个可选参数,但一个可选参数之后必须为可选参数。

//有效
/blog/{slug}/{page}
//后面的blog无效
/{page}/blog

特殊参数

除了您自己的参数之外,路由还可以包含以下任何由 Symfony 创建的特殊参数:

_controller
该参数用于确定路由匹配时执行哪个控制器和动作。
_format
匹配的值用于设置Request对象的“请求格式” 。这用于诸如设置Content-Type响应之类的事情(例如,一个json格式转换为一个application/json的Content-Type)。
_fragment
用于设置片段标识符,它是 URL 的可选最后一部分,URL以#字符开头,用于标识文档的一部分。
_locale
用于设置请求的语言环境。

额外参数

defaults路由选项中,您可以选择定义不包含在路由配置中的参数。这对于将额外的参数传递给路由的控制器很有用:

/**
 * @Route("/blog/{page}", name="blog_index", defaults={"page": 1, "title": "Hello world!"})
 */
public function index(int $page, string $title): Response
{
    // ...
}

路由参数中的斜线字符

路由参数可以包含除/斜杠字符以外的任何值,因为斜杠字符用于分隔 URL 的不同部分。例如,如果路由中的token/share/{token}包含 /字符,则此路由将不匹配。

一种可能的解决方案是将参数要求更改为更宽松:

@Route("/share/{token}", name="share", requirements={"token"=".+"})

获得路由名称和参数

/**
 * @Route("/blog", name="blog_list")
 */
public function list(Request $request): Response
{
    $routeName = $request->attributes->get('_route');
    $routeParameters = $request->attributes->get('_route_params');

    // use this to get all the available attributes (not only routing ones):
    $allAttributes = $request->attributes->all();

    // ...
}

原创文章,作者:huoxiaoqiang,如若转载,请注明出处:https://www.huoxiaoqiang.com/php/symfony/6717.html

发表评论

登录后才能评论