better-staridc-MNBT
1---
2title: 首页接管与通用路由
3description: MNBT 插件 P2 路由系统:首页接管(mnbt_register_home)与通用路由(mnbt_register_route)详解
4---
5
6# 首页接管与通用路由(V1.81 P2)
7
8本文是 [插件开发手册](./guide.md) §3.10 / §3.11 的拆分章节,介绍 P2 路由系统的两个核心 API。
9
10## 3.10 首页接管(V1.81 P2)
11
12让插件接管站点根路径 `/` 的响应。默认行为是 `header("Location: user")`,注册后可改为重定向到任意地址,或直接渲染自定义首页。
13
14```php
15mnbt_register_home(function ($ctx) {
16 // $ctx = ['path'=>'/', 'method'=>'GET', 'base'=>'']
17
18 // 模式 A:重定向到其他地址
19 return '/user/plugin.php?p=my_home&page=index';
20
21 // 模式 B:直接渲染首页内容
22 // echo '<!doctype html><h1>自定义首页</h1>';
23 // return true;
24
25 // 模式 C:不接管,回退到默认行为
26 // return false;
27}, 10);
28```
29
30**回调返回值约定:**
31
32| 返回值 | 引擎行为 |
33|--------|----------|
34| `string`(非空) | 视为重定向 URL,`header("Location: ...")` + `exit` |
35| `true` | 视为已渲染(回调内自行 `echo`),引擎 `exit` |
36| `false` / `null` | 不接管,继续下一个回调或回退到默认 `/user` |
37
38- `$priority` 数字越小越先执行(默认 10)。
39- 多个插件注册时,第一个返回 `string` 或 `true` 的回调会终止请求。
40- 回调异常会被捕获并写日志,不会中断主流程。
41- 仅当请求路径为 `/` 时才会触发;其他路径请用 [通用路由](#311-通用路由-v181-p2)。
42
43## 3.11 通用路由(V1.81 P2)
44
45让插件接管任意路径的响应,例如 `/landing`、`/promo/{id}`。路径支持命名参数,方法可限定。
46
47```php
48// 简单路径
49mnbt_register_route('GET', '/landing', function ($params, $ctx) {
50 // $ctx = ['path'=>'/landing', 'method'=>'GET', 'base'=>'', 'plugin'=>'my_plugin', 'route'=>'/landing']
51 header('Content-Type: text/html; charset=UTF-8');
52 echo '<h1>活动落地页</h1>';
53 // 不返回或返回 true → 视为已处理
54});
55
56// 带命名参数
57mnbt_register_route('GET', '/promo/{id}', function ($params, $ctx) {
58 $id = $params['id']; // 从路径提取
59 header('Content-Type: text/html; charset=UTF-8');
60 echo '<h1>推广 ID: ' . htmlspecialchars($id) . '</h1>';
61});
62
63// POST 接口
64mnbt_register_route('POST', '/api/custom-hook', function ($params, $ctx) {
65 header('Content-Type: application/json; charset=UTF-8');
66 echo json_encode(['ok' => true]);
67});
68
69// 匹配任意方法
70mnbt_register_route('*', '/health', function ($params, $ctx) {
71 echo 'ok';
72});
73```
74
75**回调返回值约定:**
76
77| 返回值 | 引擎行为 |
78|--------|----------|
79| `false` | 显式不接管,继续匹配下一个路由 |
80| `true` / `null` | 视为已处理,引擎 `exit` |
81| `string`(非空) | 若未自行输出,引擎会以 `text/html` 输出该字符串 |
82
83**路径规则:**
84
85- 必须以 `/` 开头(否则引擎自动补 `/`)。
86- 命名参数格式 `{name}`,匹配 `[^/]+`(不含斜杠的任意字符)。
87- 尾斜杠可选:注册 `/landing` 时,`/landing/` 也会匹配。
88- 路径基于站点根(已自动剥离子目录前缀),子目录部署时插件无需关心 base path。
89
90**Web 服务器配置:**
91
92通用路由支持两种访问方式:
93
94**方式一:查询参数路由(无需 rewrite,推荐)**
95
96引擎支持通过 `index.php?_r=/path` 访问任意插件路由,无需任何 Web 服务器配置。
97插件提供的 `xxx_url()` 辅助函数(如 `user_info_url()`、`balance_url()`、`hosting_url()`)
98已默认生成此格式的 URL,直接可用。
99
100```
101http://example.com/index.php?_r=/account/register
102http://example.com/index.php?_r=/balance/recharge
103http://example.com/index.php?_r=/shop
104```
105
106**方式二:伪静态路径(需 rewrite,URL 更美观)**
107
108如希望使用 `/account/register` 这样无 `index.php?_r=` 前缀的简洁 URL,
109需配置 Web 服务器把未命中实际文件的请求转发到 `index.php`:
110
111- **开发环境(PHP 内置服务器)**:`_router.php` 已自动支持,无需额外配置。
112 ```bash
113 php -S localhost:8080 _router.php
114 ```
115- **Nginx**:在站点配置中加入:
116 ```nginx
117 location / {
118 try_files $uri $uri/ /index.php?$query_string;
119 }
120 ```
121- **Apache**:在站点根目录 `.htaccess` 中加入:
122 ```apache
123 <IfModule mod_rewrite.c>
124 RewriteEngine On
125 RewriteCond %{REQUEST_FILENAME} !-f
126 RewriteCond %{REQUEST_FILENAME} !-d
127 RewriteRule ^(.*)$ index.php [QSA,L]
128 </IfModule>
129 ```
130
131参考示例:内置插件 [home_demo](./builtin/home-demo.md)(首页接管 + 通用路由演示)。