路由分组 #

一、路由前缀 #

1.1 类级别路由前缀 #

使用#[Route]属性在类上定义路由前缀:

php
<?php

namespace App\Controller;

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

#[Route('/admin')]
class AdminController extends AbstractController
{
    #[Route('/dashboard', name: 'app_admin_dashboard')]
    public function dashboard(): Response
    {
        return new Response('Admin Dashboard');
    }

    #[Route('/users', name: 'app_admin_users')]
    public function users(): Response
    {
        return new Response('Admin Users');
    }

    #[Route('/settings', name: 'app_admin_settings')]
    public function settings(): Response
    {
        return new Response('Admin Settings');
    }
}

生成的路由:

名称 路径
app_admin_dashboard /admin/dashboard
app_admin_users /admin/users
app_admin_settings /admin/settings

1.2 多级前缀 #

php
<?php

#[Route('/api')]
#[Route('/v1')]
class ApiV1Controller extends AbstractController
{
    #[Route('/users', name: 'api_v1_users')]
    public function users(): Response
    {
        return new Response('API V1 Users');
    }
}

1.3 带参数的前缀 #

php
<?php

#[Route('/{_locale}/blog', requirements: ['_locale' => 'en|zh'])]
class BlogController extends AbstractController
{
    #[Route('/list', name: 'app_blog_list')]
    public function list(): Response
    {
        return new Response('Blog List');
    }

    #[Route('/{id}', name: 'app_blog_show', requirements: ['id' => '\d+'])]
    public function show(int $id): Response
    {
        return new Response("Blog Post $id");
    }
}

二、YAML路由分组 #

2.1 路由前缀配置 #

yaml
# config/routes.yaml

admin_routes:
    path: /admin
    controller: App\Controller\AdminController::
    requirements:
        _locale: en|zh

admin_dashboard:
    path: /admin/dashboard
    controller: App\Controller\AdminController::dashboard

admin_users:
    path: /admin/users
    controller: App\Controller\AdminController::users

2.2 导入路由文件 #

yaml
# config/routes.yaml

# 导入控制器路由
controllers:
    resource:
        path: ../src/Controller/
        namespace: App\Controller
    type: attribute

# 导入Admin控制器并添加前缀
admin_routes:
    resource:
        path: ../src/Controller/Admin/
        namespace: App\Controller\Admin
    type: attribute
    prefix: /admin
    name_prefix: admin_

# 导入API控制器
api_routes:
    resource:
        path: ../src/Controller/Api/
        namespace: App\Controller\Api
    type: attribute
    prefix: /api
    name_prefix: api_

2.3 导入选项说明 #

选项 说明 示例
resource 资源路径 …/src/Controller/
type 路由类型 attribute, yaml
prefix 路径前缀 /admin
name_prefix 名称前缀 admin_
host 域名限制 api.example.com
schemes 协议限制 https
condition 条件表达式 request.isXmlHttpRequest()

三、路由组织结构 #

3.1 按模块组织控制器 #

text
src/Controller/
├── HomeController.php           # 首页控制器
├── UserController.php           # 用户控制器
├── BlogController.php           # 博客控制器
├── Admin/                       # 后台模块
│   ├── DashboardController.php
│   ├── UserController.php
│   └── SettingController.php
├── Api/                         # API模块
│   ├── UserController.php
│   ├── ProductController.php
│   └── OrderController.php
└── Frontend/                    # 前台模块
    ├── HomeController.php
    └── ProductController.php

3.2 Admin模块示例 #

php
<?php

namespace App\Controller\Admin;

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

#[Route('/admin', name: 'admin_')]
class DashboardController extends AbstractController
{
    #[Route('/', name: 'dashboard')]
    public function index(): Response
    {
        return $this->render('admin/dashboard/index.html.twig');
    }
}

#[Route('/admin/users', name: 'admin_users_')]
class UserController extends AbstractController
{
    #[Route('/', name: 'list')]
    public function list(): Response
    {
        return $this->render('admin/user/list.html.twig');
    }

    #[Route('/{id}', name: 'show', requirements: ['id' => '\d+'])]
    public function show(int $id): Response
    {
        return $this->render('admin/user/show.html.twig', ['id' => $id]);
    }

    #[Route('/new', name: 'new')]
    public function new(): Response
    {
        return $this->render('admin/user/new.html.twig');
    }
}

3.3 API模块示例 #

php
<?php

namespace App\Controller\Api;

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

#[Route('/api/v1', name: 'api_v1_')]
class UserController extends AbstractController
{
    #[Route('/users', name: 'users_list', methods: ['GET'])]
    public function list(): JsonResponse
    {
        return $this->json(['users' => []]);
    }

    #[Route('/users/{id}', name: 'users_show', methods: ['GET'])]
    public function show(int $id): JsonResponse
    {
        return $this->json(['id' => $id, 'name' => 'User ' . $id]);
    }
}

#[Route('/api/v1/products', name: 'api_v1_products_')]
class ProductController extends AbstractController
{
    #[Route('/', name: 'list', methods: ['GET'])]
    public function list(): JsonResponse
    {
        return $this->json(['products' => []]);
    }

    #[Route('/{id}', name: 'show', methods: ['GET'])]
    public function show(int $id): JsonResponse
    {
        return $this->json(['id' => $id, 'name' => 'Product ' . $id]);
    }
}

四、路由配置文件组织 #

4.1 分离路由配置 #

yaml
# config/routes.yaml

# 主路由
app_home:
    path: /
    controller: App\Controller\HomeController::index

# 导入各模块路由
admin_routes:
    resource: routes/admin.yaml
    prefix: /admin

api_routes:
    resource: routes/api.yaml
    prefix: /api

blog_routes:
    resource: routes/blog.yaml
    prefix: /blog

4.2 Admin路由配置 #

yaml
# config/routes/admin.yaml

admin_dashboard:
    path: /
    controller: App\Controller\Admin\DashboardController::index
    name: admin_dashboard

admin_users:
    resource: routes/admin_users.yaml
    prefix: /users
    name_prefix: admin_users_

4.3 Admin用户路由配置 #

yaml
# config/routes/admin_users.yaml

list:
    path: /
    controller: App\Controller\Admin\UserController::list
    methods: [GET]

show:
    path: /{id}
    controller: App\Controller\Admin\UserController::show
    requirements:
        id: \d+
    methods: [GET]

new:
    path: /new
    controller: App\Controller\Admin\UserController::new
    methods: [GET, POST]

edit:
    path: /{id}/edit
    controller: App\Controller\Admin\UserController::edit
    requirements:
        id: \d+
    methods: [GET, POST]

delete:
    path: /{id}/delete
    controller: App\Controller\Admin\UserController::delete
    requirements:
        id: \d+
    methods: [POST]

五、路由命名规范 #

5.1 命名约定 #

php
<?php

// 格式: {模块}_{资源}_{动作}

// 用户模块
#[Route('/users', name: 'user_list')]
#[Route('/users/{id}', name: 'user_show')]
#[Route('/users/new', name: 'user_new')]
#[Route('/users/{id}/edit', name: 'user_edit')]
#[Route('/users/{id}', name: 'user_delete', methods: ['DELETE'])]

// 后台用户管理
#[Route('/admin/users', name: 'admin_user_list')]
#[Route('/admin/users/{id}', name: 'admin_user_show')]
#[Route('/admin/users/new', name: 'admin_user_new')]
#[Route('/admin/users/{id}/edit', name: 'admin_user_edit')]

// API用户接口
#[Route('/api/users', name: 'api_user_list')]
#[Route('/api/users/{id}', name: 'api_user_show')]

5.2 使用name_prefix #

php
<?php

#[Route('/admin/users', name: 'admin_users_')]
class AdminUserController extends AbstractController
{
    #[Route('/', name: 'list')]           // admin_users_list
    public function list(): Response {}

    #[Route('/{id}', name: 'show')]       // admin_users_show
    public function show(int $id): Response {}

    #[Route('/new', name: 'new')]         // admin_users_new
    public function new(): Response {}

    #[Route('/{id}/edit', name: 'edit')]  // admin_users_edit
    public function edit(int $id): Response {}
}

六、条件路由 #

6.1 域名条件 #

php
<?php

#[Route('/api', host: 'api.example.com')]
class ApiController extends AbstractController
{
    #[Route('/users', name: 'api_users')]
    public function users(): Response
    {
        return $this->json(['users' => []]);
    }
}

#[Route('/admin', host: 'admin.example.com')]
class AdminController extends AbstractController
{
    #[Route('/dashboard', name: 'admin_dashboard')]
    public function dashboard(): Response
    {
        return new Response('Admin Dashboard');
    }
}

6.2 协议条件 #

php
<?php

#[Route('/secure', schemes: ['https'])]
class SecureController extends AbstractController
{
    #[Route('/page', name: 'secure_page')]
    public function page(): Response
    {
        return new Response('Secure Page');
    }
}

6.3 表达式条件 #

php
<?php

use Symfony\Component\ExpressionLanguage\Expression;

#[Route(
    '/api/internal',
    name: 'api_internal',
    condition: "request.headers.get('X-Internal-Key') === 'secret'"
)]
class InternalApiController extends AbstractController
{
    #[Route('/status', name: 'status')]
    public function status(): Response
    {
        return $this->json(['status' => 'ok']);
    }
}

6.4 YAML条件配置 #

yaml
# config/routes.yaml

api_routes:
    resource:
        path: ../src/Controller/Api/
        namespace: App\Controller\Api
    type: attribute
    prefix: /api
    host: api.example.com
    schemes: [https]
    condition: "request.headers.get('X-API-Key') === 'secret'"

七、路由优先级 #

7.1 优先级设置 #

php
<?php

class BlogController extends AbstractController
{
    #[Route('/blog/new', name: 'blog_new', priority: 10)]
    public function new(): Response
    {
        return new Response('New Blog Form');
    }

    #[Route('/blog/{slug}', name: 'blog_show')]
    public function show(string $slug): Response
    {
        return new Response("Blog: $slug");
    }
}

7.2 优先级规则 #

text
优先级规则:
1. 数字越大,优先级越高
2. 同优先级按定义顺序匹配
3. 静态路由优先于动态路由
4. 更具体的路由优先于通配路由

八、路由分组最佳实践 #

8.1 推荐结构 #

text
config/
├── routes/
│   ├── admin.yaml          # 后台路由
│   ├── api.yaml            # API路由
│   ├── frontend.yaml       # 前台路由
│   └── dev/                # 开发环境路由
│       └── profiler.yaml
└── routes.yaml             # 主路由配置

src/Controller/
├── Admin/                  # 后台控制器
│   ├── DashboardController.php
│   ├── UserController.php
│   └── ProductController.php
├── Api/                    # API控制器
│   ├── UserController.php
│   └── ProductController.php
└── Frontend/               # 前台控制器
    ├── HomeController.php
    └── ProductController.php

8.2 命名规范 #

text
路由命名规范:
├── 模块前缀: admin_, api_, frontend_
├── 资源名称: user, product, order
├── 动作后缀: _list, _show, _new, _edit, _delete
└── 示例: admin_user_list, api_product_show

九、总结 #

本章学习了:

  • 类级别路由前缀
  • YAML路由分组配置
  • 路由文件组织结构
  • 模块化控制器组织
  • 路由命名规范
  • 条件路由配置
  • 路由优先级

下一章将学习 路由高级

最后更新:2026-03-28