本文目录导读:

PHP框架的路由实现是一个核心功能,我来详细讲解其原理和实现方式。
路由的基本原理
路由的本质是将URL映射到对应的处理函数,核心流程如下:
用户请求URL → 解析URL → 匹配路由规则 → 执行对应控制器方法
简单的手动路由实现
基础版本
<?php
// index.php
$uri = $_SERVER['REQUEST_URI'];
$method = $_SERVER['REQUEST_METHOD'];
// 去除查询字符串
$uri = parse_url($uri, PHP_URL_PATH);
// 简单路由表
switch ($uri) {
case '/':
echo '首页';
break;
case '/user':
echo '用户列表';
break;
case '/user/create':
echo '创建用户';
break;
default:
http_response_code(404);
echo '页面未找到';
}
高级框架路由实现(以Laravel风格为例)
1 路由注册器
<?php
class Router
{
private array $routes = [];
private array $middlewares = [];
// 注册GET路由
public function get(string $uri, callable|array $handler): void
{
$this->routes['GET'][$uri] = $handler;
}
// 注册POST路由
public function post(string $uri, callable|array $handler): void
{
$this->routes['POST'][$uri] = $handler;
}
// 注册PUT路由
public function put(string $uri, callable|array $handler): void
{
$this->routes['PUT'][$uri] = $handler;
}
// 注册DELETE路由
public function delete(string $uri, callable|array $handler): void
{
$this->routes['DELETE'][$uri] = $handler;
}
// 路由分组
public function group(array $attributes, callable $callback): void
{
$router = new GroupRouter($this, $attributes);
$callback($router);
}
}
2 路由匹配器
<?php
class RouterDispatcher
{
private Router $router;
public function __construct(Router $router)
{
$this->router = $router;
}
/**
* 分发请求
*/
public function dispatch(string $uri, string $method): mixed
{
// 获取当前请求的所有路由
$routes = $this->getRoutesForMethod($method);
// 遍历查找匹配的路由
foreach ($routes as $routePattern => $handler) {
if ($this->matchRoute($routePattern, $uri, $matches)) {
// 调用中间件
$this->runMiddlewares($routePattern);
// 处理参数绑定
return $this->callHandler($handler, $matches);
}
}
// 未找到路由
throw new RouteNotFoundException("Route not found: $uri");
}
/**
* 匹配路由模式(支持参数)
*/
private function matchRoute(string $pattern, string $uri, ?array &$matches): bool
{
// 将路由参数转为正则
$pattern = preg_replace('/\{([a-zA-Z]+)\}/', '(?P<$1>[^/]+)', $pattern);
$pattern = '#^' . $pattern . '$#';
return (bool) preg_match($pattern, $uri, $matches);
}
/**
* 调用处理器
*/
private function callHandler(callable|array $handler, array $params): mixed
{
if (is_array($handler)) {
[$class, $method] = $handler;
$instance = new $class();
return $instance->$method(...array_values($params));
}
return $handler(...array_values($params));
}
}
3 支持中间件的路由
<?php
class Router
{
private array $middlewares = [];
/**
* 添加中间件
*/
public function middleware(string $name, callable $middleware): void
{
$this->middlewares[$name] = $middleware;
}
/**
* 注册带中间件的路由
*/
public function route(string $method, string $uri, callable|array $handler, array $middlewares = []): void
{
$this->routes[$method][$uri] = [
'handler' => $handler,
'middlewares' => $middlewares
];
}
/**
* 执行中间件链
*/
private function runMiddlewareChain(array $middlewares, Request $request, callable $finalHandler): Response
{
$pipeline = array_reduce(
array_reverse($middlewares),
function ($next, $middleware) {
return function ($request) use ($next, $middleware) {
return $middleware($request, $next);
};
},
$finalHandler
);
return $pipeline($request);
}
}
完整的路由实现示例
<?php
// 完整示例:路由系统
// 1. 定义Request类
class Request
{
public string $uri;
public string $method;
public array $query;
public array $body;
public function __construct()
{
$this->uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$this->method = $_SERVER['REQUEST_METHOD'];
$this->query = $_GET;
$this->body = $_POST;
}
}
// 2. 定义路由处理器
class UserController
{
public function index()
{
return '用户列表';
}
public function show($id)
{
return "用户ID: $id";
}
public function create()
{
return '创建用户';
}
}
// 3. 创建路由实例
$router = new Router();
$request = new Request();
// 4. 注册路由
$router->get('/', function() {
return '首页';
});
$router->get('/user', [UserController::class, 'index']);
$router->get('/user/{id}', [UserController::class, 'show']);
$router->post('/user', [UserController::class, 'create']);
// 5. 路由分组示例
$router->group(['prefix' => 'admin', 'middlewares' => ['auth']], function($router) {
$router->get('/dashboard', [AdminController::class, 'dashboard']);
$router->get('/users', [AdminController::class, 'users']);
});
// 6. 分发请求
try {
$result = $router->dispatch($request->uri, $request->method);
echo $result;
} catch (RouteNotFoundException $e) {
http_response_code(404);
echo '404 Not Found';
}
路由特性实现
1 路由缓存
<?php
class RouteCache
{
private string $cacheFile;
public function cacheRoutes(array $routes): void
{
$serialized = serialize($routes);
file_put_contents($this->cacheFile, $serialized);
}
public function getCachedRoutes(): array
{
if (file_exists($this->cacheFile)) {
return unserialize(file_get_contents($this->cacheFile));
}
return [];
}
}
2 路由优化技巧
<?php
class OptimizedRouter
{
/**
* 1. 索引路由:使用哈希表加速匹配
*/
private function indexRoutes(array $routes): array
{
$indexed = [];
foreach ($routes as $route) {
$hash = md5($route['uri'] . $route['method']);
$indexed[$hash] = $route;
}
return $indexed;
}
/**
* 2. 前缀路由:加快静态路由匹配
*/
private function matchByPrefix(string $uri): ?array
{
$staticRoutes = $this->staticRoutes;
// 如果URI在静态路由中直接匹配
if (isset($staticRoutes[$uri])) {
return $staticRoutes[$uri];
}
// 否则进行正则匹配
foreach ($this->dynamicRoutes as $pattern => $route) {
if (preg_match($pattern, $uri, $matches)) {
return ['route' => $route, 'params' => $matches];
}
}
return null;
}
}
现代PHP框架的路由实现(对比)
1 Laravel
// Laravel路由
Route::get('/user/{id}', [UserController::class, 'show'])
->where('id', '[0-9]+')
->middleware('auth');
// 路由缓存
php artisan route:cache
2 Symfony
// Symfony路由(YAML配置)
// config/routes.yaml
user_show:
path: /user/{id}
controller: App\Controller\UserController::show
requirements:
id: '\d+'
3 ThinkPHP
// ThinkPHP路由
Route::get('user/:id', 'User/read')
->pattern(['id' => '\d+'])
->middleware('auth');
路由性能优化建议
- 使用路由缓存:生产环境缓存编译好的路由
- 优化匹配顺序:静态路由优先,动态路由其次
- 使用索引结构:哈希表比数组遍历更快
- 减少正则使用:能静态匹配就不用正则
- 按需加载:只加载当前请求需要的路由
路由实现的核心是:
- 路由表:存储URL模式与处理器的映射
- 匹配算法:将当前URL与路由表匹配
- 参数提取:从URL中提取参数
- 分发执行:调用对应的控制器方法
现代框架通常还会加入:
- 中间件支持
- 路由分组
- 路由缓存
- 依赖注入容器
这就是PHP框架路由的基本实现原理。