Loading

php Hyperf框架的注解路由如何使用?

下面把 Hyperf 注解路由从 “能写” 到 “用好” 完整梳理一遍,示例代码均基于 3.x 版本(PHP 8.0+),可直接拷贝运行。

一、两种入口注解

  1. #[AutoController] —— 零配置,开箱即用

  2. #[Controller] —— 按需手工绑定,功能最全

二、#[AutoController] 用法(极简模式)

1. 基本规则

  • 只扫描 public 方法,自动生成 GET + POST 路由

  • 控制器名自动转蛇形:
    UserInfoController /user_info/{action}

  • 可附加 prefix 强行改前缀

2. 代码示例

<?php
declare(strict_types=1);
namespace App\Controller;

use Hyperf\HttpServer\Annotation\AutoController;

#[AutoController(prefix: "/v1/user")]
class UserController
{
    // 路由:GET|POST /v1/user/index
    public function index()
    {
        return ['msg' => 'list'];
    }

    // 路由:GET|POST /v1/user/profile
    public function profile()
    {
        return ['msg' => 'profile'];
    }
}

3. 常用技巧

  • 仅允许 GET:在方法里 $this->request->getMethod() 判断

  • 排除某方法:把方法改成 protected/private 即可

  • 批量加中间件:类上叠加 #[Middleware(FooMiddleware::class)]

三、#[Controller] 用法(精细模式)

1. 基本规则

  • 类本身不生成任何路由,必须配合 *Mapping 注解

  • 支持 6 种动词注解:
    GetMapping / PostMapping / PutMapping /
    PatchMapping / DeleteMapping / RequestMapping

2. 代码示例

<?php
declare(strict_types=1);
namespace App\Controller;

use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\{GetMapping, PostMapping, PutMapping, DeleteMapping};

#[Controller(prefix: "/book")]
class BookController
{
    // GET /book
    #[GetMapping(path: "/")]
    public function index()
    {
        return ['list' => []];
    }

    // GET /book/{id}
    #[GetMapping(path: "{id:\d+}")]
    public function info(int $id)
    {
        return ['id' => $id];
    }

    // POST /book
    #[PostMapping(path: "/")]
    public function create()
    {
        return ['created' => true];
    }

    // PUT /book/{id}
    #[PutMapping(path: "{id}")]
    public function update(int $id)
    {
        return ['updated' => $id];
    }

    // DELETE /book/{id}
    #[DeleteMapping(path: "{id}")]
    public function delete(int $id)
    {
        return ['deleted' => $id];
    }
}

四、路由参数与依赖注入

1. 路径参数直接写在方法形参,名与正则组名一致即可:

#[GetMapping(path: "/order/{sn:\w{12}}")]
public function detail(string $sn, RequestInterface $request)
{
    // $sn 自动注入;其余 query/post 用 $request->input()
}

2. 可再注入 RequestInterfaceResponseInterface、业务 Service 等,Hyperf 会自动从 DI 容器解析

五、中间件、分组、异常映射

1. 中间件

use Hyperf\HttpServer\Annotation\Middleware;
use App\Middleware\Auth\AdminMiddleware;

#[Controller]
#[Middleware(AdminMiddleware::class)]   // 整组生效
class AdminController
{
    // 也可以单独给某一方法再加
    #[PostMapping(path: "/login")]
    #[Middleware(GuestMiddleware::class)]
    public function login() {}
}

2. 路由分组(前缀+中间件一次性绑)

推荐在 config/routes.php 里用 Router::addGroup() 包裹,注解控制器保持 prefix="" 即可;两者可混用

3. 异常映射

config/autoload/exceptions.php 把常见异常(如 ValidationException)映射到自定义响应,注解路由无需改动

六、调试与缓存

1. 查看全部已注册路由

php bin/hyperf.php describe:routes

输出示例:

GET|POST /v1/user/index    → App\Controller\UserController::index
GET|POST /v1/user/profile  → App\Controller\UserController::profile

2. 生成路由缓存(生产环境必开)

php bin/hyperf.php route:cache

清理:

php bin/hyperf.php route:clear

七、常见坑点速查

  • 用了 #[AutoController] 却在 routes.php 又写了一遍 → 双注册,请求 404

  • 控制器没加 declare(strict_types=1); 导致注解解析失败

  • 方法非 public → 路由直接忽略

  • 正则写错 {id:\d+} 写成 {id/d+} → 整个路由失效,用 describe:routes 一眼可见

  • 3.x 必须 PHP 8.0 以上,注解语法用 #[...],旧 @... 已废弃

一张脑图总结(文字版)

AutoController —— 快速
    ↓
前缀、中间件、方法 public
    ↓
describe:routes 看结果

Controller —— 灵活
    ↓
*Mapping 动词注解 + path 正则
    ↓
参数注入 + 中间件叠加
    ↓
route:cache 上线

posted @ 2025-09-16 19:31  Carvers  阅读(28)  评论(0)    收藏  举报