1. 知识体系包含哪些部分?
(1) 动态路由的基本概念
- 什么是动态路由?
- 动态路由允许 URL 中的部分或全部路径是可变的。
- 在 Hyperf 中,可以通过占位符(如
{param}
)定义动态路径。
- 示例:
- 路径
/qq_367143/article/details/1494436
可以被解析为:/{user}/article/details/{id}
- 其中
{user}
和{id}
是动态参数。
- 路径
(2) Hyperf 的动态路由注解
- 核心注解:
#[Controller]
:标记类为控制器。#[GetMapping]
:定义GET
请求的路由规则。- 示例:
use Hyperf\HttpServer\Annotation\Controller; use Hyperf\HttpServer\Annotation\GetMapping; #[Controller] class ArticleController { #[GetMapping('/{user}/article/details/{id}')] public function article($user, $id) { return "User: {$user}, Article ID: {$id}"; } }
- 上述代码定义了一个动态路由规则,允许捕获 URL 中的
{user}
和{id}
参数。
(3) 完全动态路径的支持
- 通配符匹配:
- 如果需要将整个路径视为动态内容(如
/qq_367143/article/details/1494436
),可以使用通配符(*
或**
)。 - 示例:
#[GetMapping('/{*path}')] public function dynamicPath($path) { return "Dynamic path: {$path}"; }
- 上述代码会捕获
/qq_367143/article/details/1494436
中的所有内容,并将其作为$path
参数传递给方法。
- 如果需要将整个路径视为动态内容(如
(4) 域名绑定
- 虚拟主机支持:
- 如果需要将动态路由限制在特定域名(如
http://a.com
),可以在config/server.php
中配置虚拟主机。 - 示例:
'virtual_hosts' => [ [ 'host' => 'a.com', 'paths' => [ '/{*path}' => [ 'controller' => ArticleController::class, 'action' => 'dynamicPath', ], ], ], ],
- 上述配置确保只有
a.com
域名下的请求才会触发该动态路由规则。
- 如果需要将动态路由限制在特定域名(如
2. 底层原理是什么?
(1) 注解解析与路由注册
- 注解扫描:
- Hyperf 在服务启动阶段会扫描所有带有注解的类和方法。
- 示例:
#[Controller] class ArticleController {}
- 扫描到
#[Controller]
后,将其注册为控制器。
- 路由规则生成:
- 根据注解(如
#[GetMapping('/{*path}')]
)的内容生成对应的路由规则。 - 示例:
#[GetMapping('/{*path}')] public function dynamicPath($path) { return "Dynamic path: {$path}"; }
- 上述注解会被解析为一条路由规则:
GET /{*path}
映射到ArticleController@dynamicPath
方法。
- 根据注解(如
(2) 动态路径的解析
- 正则匹配:
- Hyperf 的路由系统基于正则表达式解析动态路径。
- 示例:
- 路由规则:
/{*path}
- 请求 URL:
/qq_367143/article/details/1494436
- 解析结果:
$path = 'qq_367143/article/details/1494436'
- 路由规则:
- 反射机制:
- 使用 PHP 的反射 API 获取方法参数的名称和类型。
- 示例:
$reflectionMethod = new ReflectionMethod(ArticleController::class, 'dynamicPath'); foreach ($reflectionMethod->getParameters() as $parameter) { echo $parameter->getName(); // 输出 "path" }
(3) 域名绑定的实现
- 虚拟主机支持:
- Hyperf 的
virtual_hosts
配置允许开发者将特定域名绑定到一组路由规则。 - 当客户端请求到达时,Swoole Server 会根据 Host 头信息匹配虚拟主机配置。
- 示例:
'virtual_hosts' => [ [ 'host' => 'a.com', 'paths' => [ '/{*path}' => [ 'controller' => ArticleController::class, 'action' => 'dynamicPath', ], ], ], ],
- 上述配置确保只有
a.com
域名下的请求才会触发该动态路由规则。
- Hyperf 的
(4) 依赖注入容器的支持
- 自动装配:
- Hyperf 的 DI 容器会根据方法签名自动注入服务实例。
- 示例:
public function dynamicPath(Database $db, $path) { return $db->select('SELECT * FROM articles WHERE path = ?', [$path]); }
$db
会被自动注入,$path
会从 URL 参数中解析。
3. 具体实现机制
以下是一个完整的示例,展示如何使用注解和配置实现完全动态路径的路由:
(1) 控制器定义
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
#[Controller]
class ArticleController
{
#[GetMapping('/{*path}')]
public function dynamicPath($path)
{
return "Dynamic path: {$path}";
}
}
- 分析:
- 定义了一个 GET 请求的路由规则,路径为
/{*path}
。 $path
参数会捕获 URL 中的所有内容。
- 定义了一个 GET 请求的路由规则,路径为
(2) 虚拟主机配置
return [
'servers' => [
[
'name' => 'http',
'type' => Server::SERVER_HTTP,
'host' => '0.0.0.0',
'port' => 9501,
'settings' => [
'open_http2_protocol' => true,
],
'callbacks' => [
Event::ON_REQUEST => [Hyperf\HttpServer\Server::class, 'onRequest'],
],
'virtual_hosts' => [
[
'host' => 'a.com',
'paths' => [
'/{*path}' => [
'controller' => ArticleController::class,
'action' => 'dynamicPath',
],
],
],
],
],
],
];
- 分析:
- 将路径
/{*path}
绑定到ArticleController@dynamicPath
方法,并限制访问域名为a.com
。
- 将路径
(3) 运行效果
- 访问
http://a.com/qq_367143/article/details/1494436
时,返回:Dynamic path: qq_367143/article/details/1494436
4. 总结
(1) 如何实现完全动态路径?
- 使用通配符:
- 使用
/{*path}
捕获 URL 中的所有内容。 - 示例:
#[GetMapping('/{*path}')] public function dynamicPath($path) { return "Dynamic path: {$path}"; }
- 使用
- 域名绑定:
- 在
config/server.php
中配置虚拟主机,将动态路径绑定到特定域名。
- 在
(2) 知识体系的核心
- 理解 Hyperf 的动态路由注解及其参数绑定机制。
- 掌握如何通过通配符实现完全动态路径。
- 学习 Hyperf 的路由解析和中间件执行流程。
(3) 底层原理
- Hyperf 使用 PHP 的反射 API 扫描注解并解析其内容。
- 注解解析器将注解转换为框架内部的路由配置。
- Swoole Server 根据 Host 头信息匹配虚拟主机配置,确保路由规则仅对特定域名生效。