阅读时间:1 分钟
0 字

路由系统

DuxLite 基于 SlimPHP 构建了简洁的路由系统。通过注解定义路由,让 API 开发变得简单直观。

基本概念

设计理念

  • 注解驱动:使用 PHP 8 注解定义路由
  • 自动发现:框架自动扫描和注册路由
  • 中间件支持:路由级别的中间件
  • 参数约束:路径参数的类型约束

核心组件

  • Route 注解:定义单个路由
  • RouteGroup 注解:定义路由组

路由注册

在使用路由注解之前,需要先注册应用以便框架能够扫描和加载路由。

应用注册

创建应用类继承 AppExtend

php
<?php

namespace App;

use Core\App\AppExtend;
use Core\Bootstrap;
use Core\Route\Route;
use Core\Auth\AuthMiddleware;
use Core\Permission\PermissionMiddleware;

class App extends AppExtend
{
    public function init(Bootstrap $app): void
    {
        // 注册路由应用,并配置中间件
        \Core\App::route()->set('api', (new Route('/api'))->addMiddleware(
            new AuthMiddleware('api')
        ));
        
        \Core\App::route()->set('web', new Route());
    }
}

配置注册

config/app.toml 中注册应用:

toml
# 应用注册
registers = [
    "App\\App"
]

这样框架就会自动扫描带有路由注解的控制器并注册路由。

基础路由

简单路由

php
use Core\Route\Attribute\Route;

class ApiController
{
    #[Route(methods: 'GET', route: '/api/hello')]
    public function hello($request, $response, $args)
    {
        return send($response, 'Hello World');
    }

    #[Route(methods: 'POST', route: '/api/users')]
    public function createUser($request, $response, $args)
    {
        $data = $request->getParsedBody();
        return send($response, '用户创建成功', $data);
    }

    // 多个 HTTP 方法
    #[Route(methods: ['GET', 'POST'], route: '/api/flexible')]
    public function flexibleMethod($request, $response, $args)
    {
        $method = $request->getMethod();
        return send($response, "处理 {$method} 请求");
    }
}

带参数的路由

php
class ApiController
{
    #[Route(methods: 'GET', route: '/api/users/{id}')]
    public function getUser($request, $response, $args)
    {
        $userId = $args['id'];
        return send($response, '用户详情', ['id' => $userId]);
    }

    #[Route(methods: 'GET', route: '/api/posts/{id}/comments/{comment_id}')]
    public function getComment($request, $response, $args)
    {
        return send($response, '评论详情', [
            'post_id' => $args['id'],
            'comment_id' => $args['comment_id']
        ]);
    }
}

命名路由

php
class ApiController
{
    #[Route(methods: 'GET', route: '/api/users/{id}', name: 'api.users.show')]
    public function getUser($request, $response, $args)
    {
        return send($response, '用户详情');
    }

    #[Route(methods: 'POST', route: '/api/users', name: 'api.users.store')]
    public function createUser($request, $response, $args)
    {
        return send($response, '用户创建成功');
    }
}

认证控制

php
class ApiController
{
    // 需要认证(默认)
    #[Route(methods: 'GET', route: '/api/profile')]
    public function getProfile($request, $response, $args)
    {
        return send($response, '用户资料');
    }

    // 无需认证
    #[Route(methods: 'GET', route: '/api/public', name: '', auth: false)]
    public function publicApi($request, $response, $args)
    {
        return send($response, '公开接口');
    }
}

Route 注解参数:

参数类型说明
methodsarray|stringHTTP 方法数组
routestring路由路径
namestring路由名称(可选)
appstring|null路由注册名(可选)
authbool是否需要认证(默认 true)

路由组

基础路由组

php
use Core\Route\Attribute\RouteGroup;

#[RouteGroup(
    app: 'api',
    route: '/api/v1',
    name: 'api.v1'
)]
class ApiV1Controller
{
    #[Route(methods: 'GET', route: '/users')]
    public function getUsers($request, $response, $args)
    {
        // 实际路径:GET /api/v1/users
        // 路由名称:api.v1.users
        return send($response, '用户列表');
    }

    #[Route(methods: 'GET', route: '/posts')]
    public function getPosts($request, $response, $args)
    {
        // 实际路径:GET /api/v1/posts
        // 路由名称:api.v1.posts
        return send($response, '文章列表');
    }
}

管理路由组

php
#[RouteGroup(
    app: 'api',
    route: '/api/admin',
    name: 'admin'
)]
class AdminController
{
    #[Route(methods: 'GET', route: '/users')]
    public function getUsers($request, $response, $args)
    {
        return send($response, '管理员用户列表');
    }

    #[Route(methods: 'PUT', route: '/settings')]
    public function updateSettings($request, $response, $args)
    {
        return send($response, '设置更新成功');
    }
}

中间件在应用注册时统一配置:

php
// App.php
\Core\App::route()->set('api', (new Route('/api'))->addMiddleware(
    new AuthMiddleware('api'),
    new PermissionMiddleware('api', \App\Models\User::class)
));

认证控制

php
#[RouteGroup(
    app: 'api',
    route: '/api/public',
    name: 'public',
    auth: false  // 组内路由默认无需认证
)]
class PublicController
{
    #[Route(methods: 'GET', route: '/info')]
    public function getInfo($request, $response, $args)
    {
        // 无需认证
        return send($response, '公开信息');
    }

    #[Route(methods: 'GET', route: '/profile', name: null, auth: true)]  // 覆盖组设置,需要认证
    public function getProfile($request, $response, $args)
    {
        // 需要认证
        return send($response, '用户资料');
    }
}

RouteGroup 注解参数:

参数类型说明
appstring路由注册名
routestring路由前缀
namestring路由名称前缀(可选)
middlewarearray中间件数组(可选)
authbool是否需要认证(默认 true)

命名路由

定义命名路由

php
class ApiController
{
    #[Route(methods: 'GET', route: '/api/users/{id}', name: 'api.users.show')]
    public function getUser($request, $response, $args)
    {
        return send($response, '用户详情');
    }
}

生成 URL

php
// 生成 URL
$userUrl = url('api.users.show', ['id' => 123]);
// 结果:/api/users/123

// 在响应中使用
class UserController
{
    public function getUser($request, $response, $args)
    {
        $userId = $args['id'];
        
        $data = [
            'id' => $userId,
            'links' => [
                'self' => url('api.users.show', ['id' => $userId]),
                'edit' => url('api.users.edit', ['id' => $userId])
            ]
        ];
        
        return send($response, '用户详情', $data);
    }
}

请求处理

获取请求数据

php
class ApiController
{
    #[Route(methods: 'GET', route: '/api/search')]
    public function search($request, $response, $args)
    {
        // 查询参数
        $params = $request->getQueryParams();
        $keyword = $params['q'] ?? '';
        
        return send($response, '搜索结果', ['keyword' => $keyword]);
    }

    #[Route(methods: 'POST', route: '/api/users')]
    public function createUser($request, $response, $args)
    {
        // POST 数据
        $data = $request->getParsedBody();
        
        return send($response, '用户创建成功', $data);
    }

    #[Route(methods: 'POST', route: '/api/upload')]
    public function upload($request, $response, $args)
    {
        // 上传文件
        $files = $request->getUploadedFiles();
        $file = $files['file'] ?? null;
        
        if (!$file) {
            throw new ExceptionBusiness('请选择文件');
        }
        
        return send($response, '上传成功');
    }
}

响应处理

标准响应

php
class ApiController
{
    public function getUsers($request, $response, $args)
    {
        // 成功响应
        return send($response, '获取成功', $users);
    }
}