路由基础 #
一、路由概述 #
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