symfony配置文件之三:routing和路由配置

目录

1、创建路由

2、查看路由列表

3、本地化路由(i18n)

4、添加requirements (针对url占位符或host占位符)

1)类正则 Regex Requirements

2)HTTP Method Requirements

3)Host-Based Requirements

        在主机名中使用占位符

        导入路由的主机匹配

        测试控制器

4)Dynamic Requirements with Condition Expressions 通过条件限制路由匹配


        漂亮的路由对任何一个WEB应用而言都是刚需。这意味着我们要抛弃类似 index.php?article_id=57 这样丑陋的URL, 而使用像 /read/intro-to-symfony 语义化的url。

        灵活性也是非常重要的。 如果你需要把你页面所有的/blog变成/news?,你要查找多少次, 替换多少次? 如果你使用Symfony的路由器, 那改个URL什么的就变得非常非常简单。

        Symfony路由器可以让你定义出各种个性化的URL, 映射到你应用的各个地方。了解完这个章节后, 你会:

    创建复杂的路由映射到控制器

    在控制器和模板中生成URL

    从包中加载路由资源(或者说任何地方)
 
    调试路由

1、创建路由

        简单说,路由就是一个从URL路径到控制器映射。 如果你想匹配 /blog,以及类似 /blog/my-post 或 /blog/all-about-symfony 的URL路径,并且将它们分发到对应的控制器,并且渲染一个blog实体.。要实现这个功能非常简单,主要有一下几种方法:

--------通过注释定义路由 
--------通过yaml配置文件定义路由 
--------通过xml配置文件定义路由 
--------通过php配置文件定义路由

        路由可以在YAML,XML和PHP中配置,所有格式都提供相同的功能和性能,因此请选择您喜欢的格式。如果选择PHP注释,请在应用程序中运行此命令一次以添加对它们的支持:

  $ composer require annotations

       现在,您可以配置路由:

注释形式

// src/Controller/BlogController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

class BlogController extends AbstractController
{
    /**
     * Matches /blog exactly
     *
     * @Route("/blog", name="blog_list")
     */
    public function list()
    {
        // ...
    }

    /**
     * Matches /blog/*
     *
     * @Route("/blog/{slug}", name="blog_show")
     */
    public function show($slug)
    {
        // $slug will equal the dynamic part of the URL
        // e.g. at /blog/yay-routing, then $slug='yay-routing'

        // ...
    }
}

YAML文件

# config/routes.yaml
blog_list:
    path:     /blog
    controller: App\Controller\BlogController::list

blog_show:
    path:     /blog/{slug}
    controller: App\Controller\BlogController::show

XML文件

<!-- config/routes.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/routing
        http://symfony.com/schema/routing/routing-1.0.xsd">

    <route id="blog_list" path="/blog" controller="App\Controller\BlogController::list">
        <!-- settings -->
    </route>

    <route id="blog_show" path="/blog/{slug}" controller="App\Controller\BlogController::show">
        <!-- settings -->
    </route>
</routes>

PHP文件

// config/routes.php
namespace Symfony\Component\Routing\Loader\Configurator;

use App\Controller\BlogController;

return function (RoutingConfigurator $routes) {
    $routes->add('blog_list', '/blog')
        ->controller([BlogController::class, 'list'])
    ;
    $routes->add('blog_show', '/blog/{slug}')
        ->controller([BlogController::class, 'show'])
    ;
};
  • 如果去匹配路径 /blog,那么将执行第一条路由,并且 list() 方法被调用。
  • 如果去匹配 /blog/*,那么将执行第一条路由,并且 show() 方法被调用。由于路由的路径设置为 /blog/{slug},那么 /blog/ 后面的字符串,将传递给 show() 方法的参数 $slug。例如,如果去匹配 /blog/yay-routing,那么参数 $slug 将被赋值为字符串"yay-routing"

        只要您的路径中有一个{placeholder}占位符,该部分就会成为通配符:它匹配任何值。现在,您的控制器可以拥有一个$placeholder参数(此处,通配符和参数名称必须匹配)。

2、查看路由列表

        随着应用程序的开发,最终将拥有大量的路由。要查看所有的路由列表,请运行:

$ php bin/console debug:router
------------------------------ -------- -------------------------------------
Name Method Path
------------------------------ -------- -------------------------------------
app_lucky_number ANY /lucky/number/{max}
...
------------------------------ -------- -------------------------------------

3、本地化路由(i18n)

        路由可以本地化,以提供一个与区域相关的唯一路径。Symfony提供了一种方便的方式来声明本地化路由,且无需重复声明。

注释

// src/Controller/CompanyController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

class CompanyController extends AbstractController
{
    /**
     * @Route({
     *     "nl": "/over-ons",
     *     "en": "/about-us"
     * }, name="about_us")
     */
    public function about()
    {
        // ...
    }
}

YAML文件

# config/routes.yaml
about_us:
    path:
        nl: /over-ons
        en: /about-us
    controller: App\Controller\CompanyController::about

XML文件

<!-- config/routes.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/routing
        http://symfony.com/schema/routing/routing-1.0.xsd">

    <route id="about_us" controller="App\Controller\CompanyController::about">
        <path locale="nl">/over-ons</path>
        <path locale="en">/about-us</path>
    </route>
</routes>

PHP文件

// config/routes.php
namespace Symfony\Component\Routing\Loader\Configurator;

use App\Controller\CompanyController;

return function (RoutingConfigurator $routes) {
    $routes->add('about_us', ['nl' => '/over-ons', 'en' => '/about-us'])
        ->controller([CompanyController::class, 'about']);
};

        当本地化路由被匹配时,Symfony就会自动知道在请求期间应使用哪个区域的设置。以这种方式定义路由,消除了对路由重复注册的需要,同时最小化了由定义不一致引起的任何错误风险。

notes

        如果应用程序使用 “完整语言 + 领土区域设置”(例如fr_FR, fr_BE),你可以在你的路由中仅仅使用语言部分(如fr)。当您希望为共享相同语言的语言环境使用相同的路径时,这可以防止必须定义多个路径。

        国际化应用程序的一个常见要求是,为所有路由添加前缀。这可以通过为每个语言环境定义不同的前缀来完成(如果您愿意,可以为默认语言环境设置一个空前缀):

YAML文件

# config/routes/annotations.yaml
controllers:
    resource: '../../src/Controller/'
    type: annotation
    prefix:
        en: '' # don't prefix URLs for English, the default locale
        nl: '/nl'

XML文件

<!-- config/routes/annotations.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/routing
        http://symfony.com/schema/routing/routing-1.0.xsd">

    <import resource="../src/Controller/" type="annotation">
        <!-- don't prefix URLs for English, the default locale -->
        <prefix locale="en"></prefix>
        <prefix locale="nl">/nl</prefix>
    </import>
</routes>

PHP文件

// config/routes/annotations.php
namespace Symfony\Component\Routing\Loader\Configurator;

return function (RoutingConfigurator $routes) {
    $routes->import('../src/Controller/', 'annotation')
        ->prefix([
            // don't prefix URLs for English, the default locale
            'en' => '',
            'nl' => '/nl'
        ])
    ;
};

4、添加requirements (针对url占位符或host占位符)

        想象一下,该 blog_list路由将包含一个分页的 blog post 列表,其中包含/blog/2和/blog/3来表示第2页和第3页的URL 。如果您更改路由的路径为 /blog/{page},则会遇到问题:

  • blog_list: /blog/{page} 会匹配 /blog/* ;
  • blog_show:/blog/{slug} 将同样匹配 /blog/* 。

        当两个路由匹配相同的URL时,加载的第一个路由获胜。不幸的是,这意味着/blog/yay-routing 将匹配 blog_list。这是个比较严重的问题。

        为了解决这个问题,增加 requirements 属性来限制通配符{page}只能匹配数字:

注释形式

// src/Controller/BlogController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

class BlogController extends AbstractController
{
    /**
     * @Route("/blog/{page}", name="blog_list", requirements={"page"="\d+"})
     */
    public function list($page)
    {
        // ...
    }

    /**
     * @Route("/blog/{slug}", name="blog_show")
     */
    public function show($slug)
    {
        // ...
    }
}

YAML文件

# config/routes.yaml
blog_list:
    path:      /blog/{page}
    controller: App\Controller\BlogController::list
    requirements:
        page: '\d+'

blog_show:
    # ...

XML文件

<!-- config/routes.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/routing
        http://symfony.com/schema/routing/routing-1.0.xsd">

    <route id="blog_list" path="/blog/{page}" controller="App\Controller\BlogController::list">
        <requirement key="page">\d+</requirement>
    </route>

    <!-- ... -->
</routes>

PHP文件

// config/routes.php
namespace Symfony\Component\Routing\Loader\Configurator;

use App\Controller\BlogController;

return function (RoutingConfigurator $routes) {
    $routes->add('blog_list', '/blog/{page}')
        ->controller([BlogController::class, 'list'])
        ->requirements(['page' => '\d+'])
    ;
    // ...
};

        这个\d+是一个匹配任意长度数字正则表达式。现在:

 

           网址

路线

            参数

/blog/2blog_list$page = 2
/blog/yay-routingblog_show$slug = yay-routing

        如果您愿意,也可以使用{placeholder_name<requirements>}语法,在每个占位符中后面使用<>写成同行形式 。此功能使配置更简洁,但是当需求复杂时,它降低了路由的可读性:

注释形式

// src/Controller/BlogController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

class BlogController extends AbstractController
{
    /**
     * @Route("/blog/{page<\d+>}", name="blog_list")
     */
    public function list($page)
    {
        // ...
    }
}

YAML形式

# config/routes.yaml
blog_list:
    path:      /blog/{page<\d+>}
    controller: App\Controller\BlogController::list

XML形式

<!-- config/routes.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/routing
        http://symfony.com/schema/routing/routing-1.0.xsd">

    <route id="blog_list" path="/blog/{page<\d+>}" controller="App\Controller\BlogController::list" />

    <!-- ... -->
</routes>

PHP文件

// config/routes.php
namespace Symfony\Component\Routing\Loader\Configurator;

use App\Controller\BlogController;

return function (RoutingConfigurator $routes) {
    $routes->add('blog_list', '/blog/{page<\d+>}')
        ->controller([BlogController::class, 'list'])
    ;
    // ...
};

定义requirements的语法总结:

1)类正则 Regex Requirements

        如多语言本地化枚举的实现:

注释形式 

// src/Controller/MainController.php

// ...
class MainController extends AbstractController
{
    /**
     * @Route("/{_locale}", defaults={"_locale"="en"}, requirements={
     *     "_locale"="en|fr"
     * })
     */
    public function homepage($_locale)
    {
    }
}

YAML文件

# config/routes.yaml
homepage:
    path:       /{_locale}
    controller: App\Controller\MainController::homepage
    defaults:   { _locale: en }
    requirements:
        _locale:  en|fr

XML文件

<!-- config/routes.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/routing
        http://symfony.com/schema/routing/routing-1.0.xsd">

    <route id="homepage" path="/{_locale}" controller="App\Controller\MainController::homepage">
        <default key="_locale">en</default>
        <requirement key="_locale">en|fr</requirement>
    </route>
</routes>

PHP文件

// config/routes.php
namespace Symfony\Component\Routing\Loader\Configurator;

use App\Controller\MainController;

return function (RoutingConfigurator $routes) {
    $routes->add('homepage', '/{_locale}')
        ->controller([MainController::class, 'homepage'])
        ->defaults([
            '_locale' => 'en',
        ])
        ->requirements([
            '_locale' => 'en|fr',
        ])
    ;
};

        对于传入的请求,URL 的{_locale}部分与正则表达式(en|fr)匹配。

路径参数
/{_locale} = "en"
/en{_locale} = "en"
/fr{_locale} = "fr"
/es不符合这条路线

注意

        在声明或导入路由时,通过设置utf8选项,可以启用UTF-8路由匹配。这将使得例如 在requirements中的 . 将匹配任何UTF-8字符而不是单个字节。

提示:

        路由requirements还可以包括容器参数,如本文中所述。当正则表达式非常复杂,并在您的应用程序中重复使用时,这会派上用场。如:

# config/routes.yaml
contact:
    path:       /{_locale}/contact
    controller: App\Controller\MainController::contact
    requirements:
        _locale: '%app.locales%'

2)HTTP Method Requirements

        除了URL之外,您还可以匹配传入请求的方法(即GET,HEAD,POST,PUT,DELETE)。假设,您为博客创建了一个API,并且您有两条路由:一条用于显示帖子(在GET或HEAD请求上),另一条用于更新帖子(在PUT请求中)。这可以通过以下路由配置来完成:

注释形式

// src/Controller/BlogApiController.php
namespace App\Controller;

// ...

class BlogApiController extends AbstractController
{
    /**
     * @Route("/api/posts/{id}", methods={"GET","HEAD"})
     */
    public function show($id)
    {
        // ... return a JSON response with the post
    }

    /**
     * @Route("/api/posts/{id}", methods={"PUT"})
     */
    public function edit($id)
    {
        // ... edit a post
    }
}

YAML文本

# config/routes.yaml
api_post_show:
    path:       /api/posts/{id}
    controller: App\Controller\BlogApiController::show
    methods:    GET|HEAD

api_post_edit:
    path:       /api/posts/{id}
    controller: App\Controller\BlogApiController::edit
    methods:    PUT

XML文本

<!-- config/routes.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/routing
        http://symfony.com/schema/routing/routing-1.0.xsd">

    <route id="api_post_show"
        path="/api/posts/{id}"
        controller="App\Controller\BlogApiController::show"
        methods="GET|HEAD" />

    <route id="api_post_edit"
        path="/api/posts/{id}"
        controller="App\Controller\BlogApiController::edit"
        methods="PUT" />
</routes>

PHP文本

// config/routes.php
namespace Symfony\Component\Routing\Loader\Configurator;

use App\Controller\BlogApiController;

return function (RoutingConfigurator $routes) {
    $routes->add('api_post_show', '/api/posts/{id}')
        ->controller([BlogApiController::class, 'show'])
        ->methods(['GET', 'HEAD'])
    ;
    $routes->add('api_post_edit', '/api/posts/{id}')
        ->controller([BlogApiController::class, 'edit'])
        ->methods(['PUT'])
    ;

    // or use collection
    $api = $routes->collection('api_post_')
        ->prefix('/api/posts/{id}')
    ;
    $api->add('show')
        ->controller([BlogApiController::class, 'show'])
        ->methods(['GET', 'HEAD'])
    ;
    $api->add('edit')
        ->controller([BlogApiController::class, 'edit'])
        ->methods(['PUT'])
    ;
};

        尽管这两条路由具有相同的路径(/api/posts/{id}),但第一条路径仅匹配GET或HEAD请求,第二条路径仅匹配PUT请求。这意味着,您可以使用相同的URL显示和编辑帖子,同时为这两个操作使用不同的控制器。

注意

        如果未指定methods,则路由将匹配所有方法。

提示:

        如果您使用HTML表单和HTTP方法,而不是GETPOST,那么你需要包括一个_method参数来伪装HTTP方法。有关更多信息,请参见 如何更改窗体的操作和方法

3)Host-Based Requirements

        您还可以对传入请求的HTTP 主机,进行路由匹配。这种Requirements主要用于限制请求的来源。如:

注释形式

// src/Controller/MainController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

class MainController extends AbstractController
{
    /**
     * @Route("/", name="mobile_homepage", host="m.example.com")
     */
    public function mobileHomepage()
    {
        // ...
    }

    /**
     * @Route("/", name="homepage")
     */
    public function homepage()
    {
        // ...
    }
}

YAML文件

# config/routes.yaml
mobile_homepage:
    path:       /
    host:       m.example.com
    controller: App\Controller\MainController::mobileHomepage

homepage:
    path:       /
    controller: App\Controller\MainController::homepage

XML文件

<!-- config/routes.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/routing
        http://symfony.com/schema/routing/routing-1.0.xsd">

    <route id="mobile_homepage"
        path="/"
        host="m.example.com"
        controller="App\Controller\MainController::mobileHomepage" />

    <route id="homepage" path="/" controller="App\Controller\MainController::homepage" />
</routes>

PHP文件

// config/routes.php
namespace Symfony\Component\Routing\Loader\Configurator;

use App\Controller\MainController;

return function (RoutingConfigurator $routes) {
    $routes->add('mobile_homepage', '/')
        ->controller([MainController::class, 'mobileHomepage'])
        ->host('m.example.com')
    ;
    $routes->add('homepage', '/')
        ->controller([MainController::class, 'homepage'])
    ;
};

return $routes;

        两条路径匹配相同的路径/,但第一条路径仅在主机为m.example.com时匹配。

在主机名中使用占位符

        此外,主机名与路径匹配系统拥有相同的语法,这就意味着可以在主机名中使用占位符,如{project}等。占位符也可以使用defaults设置和requirements设置,并且占位符的requirements规则也可使用服务参数。如下所示:

注释形式

// src/Controller/MainController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

class MainController extends AbstractController
{
    /**
     * @Route(
     *     "/",
     *     name="mobile_homepage",
     *     host="m.{domain}",
     *     defaults={"domain"="%domain%"},
     *     requirements={"domain"="%domain%"}
     * )
     */
    public function mobileHomepage()
    {
        // ...
    }

    /**
     * @Route("/", name="homepage")
     */
    public function homepage()
    {
        // ...
    }
}

YAML形式

# config/routes.yaml
mobile_homepage:
    path:       /
    host:       "m.{domain}"
    controller: App\Controller\MainController::mobileHomepage
    defaults:
        domain: '%domain%'
    requirements:
        domain: '%domain%'

homepage:
    path:       /
    controller: App\Controller\MainController::homepage

XML文件

<!-- config/routes.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/routing
        http://symfony.com/schema/routing/routing-1.0.xsd">

    <route id="mobile_homepage"
        path="/"
        host="m.{domain}"
        controller="App\Controller\MainController::mobileHomepage">
        <default key="domain">%domain%</default>
        <requirement key="domain">%domain%</requirement>
    </route>

    <route id="homepage" path="/" controller="App\Controller\MainController::homepage" />
</routes>

PHP文件

// config/routes.php
namespace Symfony\Component\Routing\Loader\Configurator;

use App\Controller\MainController;

return function (RoutingConfigurator $routes) {
    $routes->add('mobile_homepage', '/')
        ->controller([MainController::class, 'mobileHomepage'])
        ->host('m.{domain}')
        ->defaults([
            'domain' => '%domain%',
        ])
        ->requirements([
            'domain' => '%domain%',
        ])
    ;
    $routes->add('homepage', '/')
        ->controller([MainController::class, 'homepage'])
    ;
};

导入路由的主机匹配

        最后,我们还可以使用导入路由的主机匹配,在导入路由的路径上设置主机选项。如下所示:

注释形式

// src/Controller/MainController.php
namespace Acme\HelloBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

/**
 * @Route(host="hello.example.com")
 */
class MainController extends AbstractController
{
    // ...
}

YAML文件

# config/routes.yaml
app_hello:
    resource: '@AcmeHelloBundle/Resources/config/routing.yaml'
    host:     "hello.example.com"
    controller: Acme\HelloBundle\Controller\MainController # 自行修改后添加,???
# 以上注释形式的路由定义,是在MainController下的路由代入,为什么在配置文件中没有体现呢?

XML文件

<!-- config/routes.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/routing
        http://symfony.com/schema/routing/routing-1.0.xsd"> 
    <import resource="@AcmeHelloBundle/Resources/config/routing.xml" host="hello.example.com" />
</routes>

PHP文件

// config/routes.php
$routes = $loader->import("@AcmeHelloBundle/Resources/config/routing.php");
$routes->setHost('hello.example.com');

return $routes;

 

测试控制器

如果要在功能测试中获取过去的url匹配,则需要在请求对象上设置Host HTTP标头:

1
2
3
4
5
6
7
$crawler = $client->request(
    'GET',
    '/homepage',
    [],
    [],
    ['HTTP_HOST' => 'm.' . $client->getContainer()->getParameter('domain')]
);

4)Dynamic Requirements with Condition Expressions 通过条件限制路由匹配

        路由匹配,除了可以通过"路由占位符"、"HTTP方法"或"主机名"外,如果需要更灵活地定义任意匹配逻辑,还可以使用conditions路由选项。如下所示:

注释形式

// src/Controller/DefaultController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

class DefaultController extends AbstractController
{
    /**
     * @Route(
     *     "/contact",
     *     name="contact",
     *     condition="context.getMethod() in ['GET', 'HEAD'] and request.headers.get('User-Agent') matches '/firefox/i'"
     * )
     *
     * expressions can also include config parameters
     * condition: "request.headers.get('User-Agent') matches '%app.allowed_browsers%'"
     */
    public function contact()
    {
        // ...
    }
}

YAML文件

# config/routes.yaml
contact:
    path:       /contact
    controller: 'App\Controller\DefaultController::contact'
    condition:  "context.getMethod() in ['GET', 'HEAD'] and request.headers.get('User-Agent') matches '/firefox/i'"
    # expressions can also include config parameters
    # condition: "request.headers.get('User-Agent') matches '%app.allowed_browsers%'"

XML文件

<!-- config/routes.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/routing
        http://symfony.com/schema/routing/routing-1.0.xsd">

    <route id="contact" path="/contact" controller="App\Controller\DefaultController::contact">
        <condition>context.getMethod() in ['GET', 'HEAD'] and request.headers.get('User-Agent') matches '/firefox/i'</condition>
        <!-- expressions can also include config parameters -->
        <!-- <condition>request.headers.get('User-Agent') matches '%app.allowed_browsers%'</condition> -->
    </route>
</routes>

PHP文件

// config/routes.php
namespace Symfony\Component\Routing\Loader\Configurator;

use App\Controller\DefaultController;

return function (RoutingConfigurator $routes) {
    $routes->add('contact', '')
        ->controller([DefaultController::class, 'contact'])
        ->condition('context.getMethod() in ["GET", "HEAD"] and request.headers.get("User-Agent") matches "/firefox/i"')
        // expressions can also include config parameters
        // 'request.headers.get("User-Agent") matches "%app.allowed_browsers%"'
    ;
};

         这个condition是一个表达式,您可以在此处了解有关其语法的更多信息:表达式语法https://symfony.com/doc/current/components/expression_language/syntax.html。此处的匹配逻辑是,HTTP方法是GET或HEAD,并且请求的User-Agent 报头中含有firefox字样

         您可以通过利用传递到表达式中的两个变量,来执行表达式中所需的任何复杂逻辑:

context

        一个实例RequestContext,其中包含有关匹配路由的最基本信息。

request

        Symfony Request对象(请参阅请求)。

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值