路由基础 #

一、路由概述 #

1.1 什么是路由 #

路由是将URL映射到控制器动作的机制。当用户访问一个URL时,Symfony路由系统会找到对应的控制器来处理请求。

text
┌─────────────────────────────────────────────────────┐
│                    路由工作流程                      │
├─────────────────────────────────────────────────────┤
│                                                     │
│   用户请求 URL                                       │
│       ↓                                             │
│   路由组件匹配                                       │
│       ↓                                             │
│   找到对应控制器                                     │
│       ↓                                             │
│   执行控制器方法                                     │
│       ↓                                             │
│   返回响应                                          │
│                                                     │
└─────────────────────────────────────────────────────┘

1.2 路由配置方式 #

Symfony支持多种路由配置方式:

方式 说明 推荐场景
PHP属性 在控制器中使用#[Route]属性 推荐,最常用
YAML配置 在config/routes.yaml中配置 传统项目
XML配置 在config/routes.xml中配置 企业项目
PHP代码 在config/routes.php中配置 特殊需求

二、PHP属性路由 #

2.1 基本用法 #

php
<?php

namespace App\Controller;

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

class HomeController extends AbstractController
{
    #[Route('/', name: 'app_home')]
    public function index(): Response
    {
        return new Response('Home Page');
    }

    #[Route('/about', name: 'app_about')]
    public function about(): Response
    {
        return new Response('About Page');
    }

    #[Route('/contact', name: 'app_contact')]
    public function contact(): Response
    {
        return new Response('Contact Page');
    }
}

2.2 路由属性参数 #

php
<?php

use Symfony\Component\Routing\Annotation\Route;

class ProductController extends AbstractController
{
    #[Route(
        path: '/products',
        name: 'app_product_list',
        methods: ['GET'],
        requirements: [],
        defaults: [],
        host: 'example.com',
        schemes: ['https'],
        condition: "request.headers.get('X-API-Key') === 'secret'"
    )]
    public function list(): Response
    {
        return new Response('Product List');
    }
}

2.3 属性参数说明 #

参数 说明 示例
path URL路径 ‘/products’
name 路由名称 ‘app_product_list’
methods HTTP方法 [‘GET’, ‘POST’]
requirements 参数约束 [‘id’ => ‘\d+’]
defaults 默认值 [‘page’ => 1]
host 域名限制 api.example.com
schemes 协议限制 [‘https’]
condition 条件表达式 “request.isXmlHttpRequest()”

三、YAML配置路由 #

3.1 基本配置 #

yaml
# config/routes.yaml

app_home:
    path: /
    controller: App\Controller\HomeController::index

app_about:
    path: /about
    controller: App\Controller\HomeController::about

app_contact:
    path: /contact
    controller: App\Controller\HomeController::contact
    methods: [GET, POST]

3.2 带参数的路由 #

yaml
# config/routes.yaml

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

app_blog_post:
    path: /blog/{year}/{month}/{slug}
    controller: App\Controller\BlogController::show
    requirements:
        year: \d{4}
        month: \d{2}
    defaults:
        month: null

3.3 路由导入 #

yaml
# config/routes.yaml

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

# 导入Bundle路由
app_bundle_routes:
    resource: '@AppBundle/Resources/config/routes.yaml'

四、路由参数 #

4.1 基本参数 #

php
<?php

class UserController extends AbstractController
{
    #[Route('/user/{id}', name: 'app_user_show')]
    public function show(int $id): Response
    {
        return new Response("User ID: $id");
    }

    #[Route('/category/{category}/product/{productId}', name: 'app_product_show')]
    public function productShow(string $category, int $productId): Response
    {
        return new Response("Category: $category, Product: $productId");
    }
}

4.2 参数约束 #

php
<?php

class ArticleController extends AbstractController
{
    #[Route('/article/{id}', name: 'app_article_show', requirements: ['id' => '\d+'])]
    public function show(int $id): Response
    {
        return new Response("Article ID: $id");
    }

    #[Route('/page/{slug}', name: 'app_page_show', requirements: ['slug' => '[a-z-]+'])]
    public function pageShow(string $slug): Response
    {
        return new Response("Page Slug: $slug");
    }

    #[Route('/api/{version}', name: 'app_api', requirements: ['version' => 'v1|v2|v3'])]
    public function api(string $version): Response
    {
        return new Response("API Version: $version");
    }
}

4.3 常用正则约束 #

约束 说明 示例
\d+ 数字 ‘123’
[a-z]+ 小写字母 ‘hello’
[a-zA-Z]+ 字母 ‘Hello’
[a-z0-9-]+ 字母数字横线 ‘my-page-1’
.+ 任意字符 ‘any/thing’
v1|v2|v3 枚举值 ‘v1’, ‘v2’

4.4 默认值 #

php
<?php

class BlogController extends AbstractController
{
    #[Route('/blog/{page}', name: 'app_blog_list', defaults: ['page' => 1])]
    public function list(int $page): Response
    {
        return new Response("Blog Page: $page");
    }

    #[Route('/search/{category}/{keyword}', name: 'app_search', defaults: ['category' => 'all', 'keyword' => null])]
    public function search(string $category, ?string $keyword): Response
    {
        return new Response("Category: $category, Keyword: $keyword");
    }
}

五、HTTP方法限制 #

5.1 单一方法 #

php
<?php

class ApiController extends AbstractController
{
    #[Route('/api/users', name: 'api_users_list', methods: ['GET'])]
    public function listUsers(): Response
    {
        return $this->json(['users' => []]);
    }

    #[Route('/api/users', name: 'api_users_create', methods: ['POST'])]
    public function createUser(): Response
    {
        return $this->json(['status' => 'created'], 201);
    }

    #[Route('/api/users/{id}', name: 'api_users_update', methods: ['PUT'])]
    public function updateUser(int $id): Response
    {
        return $this->json(['status' => 'updated']);
    }

    #[Route('/api/users/{id}', name: 'api_users_delete', methods: ['DELETE'])]
    public function deleteUser(int $id): Response
    {
        return $this->json(['status' => 'deleted']);
    }
}

5.2 多方法支持 #

php
<?php

class FormController extends AbstractController
{
    #[Route('/form', name: 'app_form', methods: ['GET', 'POST'])]
    public function form(): Response
    {
        return new Response('Form Page');
    }
}

六、特殊路由 #

6.1 带后缀的路由 #

php
<?php

class PageController extends AbstractController
{
    #[Route('/page/{slug}.html', name: 'app_page_html')]
    public function pageHtml(string $slug): Response
    {
        return new Response("Page: $slug");
    }

    #[Route('/feed.{_format}', name: 'app_feed', requirements: ['_format' => 'xml|json'])]
    public function feed(string $_format): Response
    {
        return new Response("Feed Format: $_format");
    }
}

6.2 优先级路由 #

php
<?php

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

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

七、路由调试 #

7.1 查看所有路由 #

bash
# 查看所有路由
php bin/console debug:router

# 输出示例
+-------------------+-----------+------------+---------------------+
| Name              | Method    | Scheme     | Path                |
+-------------------+-----------+------------+---------------------+
| app_home          | ANY       | ANY        | /                   |
| app_about         | ANY       | ANY        | /about              |
| app_user_show     | ANY       | ANY        | /user/{id}          |
| app_blog_list     | ANY       | ANY        | /blog/{page}        |
+-------------------+-----------+------------+---------------------+

7.2 查看特定路由 #

bash
# 查看特定路由详情
php bin/console debug:router app_user_show

# 输出示例
+--------------+---------------------------------------------------------+
| Property     | Value                                                   |
+--------------+---------------------------------------------------------+
| Route Name   | app_user_show                                           |
| Path         | /user/{id}                                              |
| Path Regex   | #^/user/(?P<id>\d+)$#sD                                 |
| Host         | ANY                                                     |
| Host Regex   |                                                         |
| Scheme       | ANY                                                     |
| Method       | ANY                                                     |
| Requirements | id: \d+                                                 |
| Defaults     | _controller: App\Controller\UserController::show       |
+--------------+---------------------------------------------------------+

7.3 匹配测试 #

bash
# 测试URL匹配
php bin/console router:match /user/123

# 输出示例
[OK] Route "app_user_show" matches

+--------------+---------------------------------------------------------+
| Property     | Value                                                   |
+--------------+---------------------------------------------------------+
| Route Name   | app_user_show                                           |
| Path         | /user/{id}                                              |
| Parameters   | id: 123                                                 |
+--------------+---------------------------------------------------------+

八、路由最佳实践 #

8.1 命名规范 #

php
<?php

// 好的命名
#[Route('/users', name: 'app_user_list')]
#[Route('/users/{id}', name: 'app_user_show')]
#[Route('/users/new', name: 'app_user_new')]
#[Route('/users/{id}/edit', name: 'app_user_edit')]
#[Route('/users/{id}', name: 'app_user_delete', methods: ['DELETE'])]

// 不好的命名
#[Route('/users', name: 'users')]
#[Route('/users/{id}', name: 'user')]
#[Route('/users/new', name: 'new_user')]

8.2 RESTful路由设计 #

php
<?php

class UserController extends AbstractController
{
    #[Route('/users', name: 'app_user_list', methods: ['GET'])]
    public function list(): Response {}

    #[Route('/users', name: 'app_user_create', methods: ['POST'])]
    public function create(): Response {}

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

    #[Route('/users/{id}', name: 'app_user_update', methods: ['PUT', 'PATCH'])]
    public function update(int $id): Response {}

    #[Route('/users/{id}', name: 'app_user_delete', methods: ['DELETE'])]
    public function delete(int $id): Response {}
}

8.3 路由组织 #

php
<?php

// 使用类级别路由前缀
#[Route('/admin')]
class AdminController extends AbstractController
{
    #[Route('/dashboard', name: 'app_admin_dashboard')]
    public function dashboard(): Response {}

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

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

九、总结 #

本章学习了:

  • 路由基本概念和工作流程
  • PHP属性路由配置
  • YAML路由配置
  • 路由参数和约束
  • HTTP方法限制
  • 路由调试命令
  • 路由最佳实践

下一章将学习 路由参数

最后更新:2026-03-28