zhamao-framework/docs/event/route-annotations.md

238 lines
7.8 KiB
Markdown
Raw Normal View History

2020-12-23 16:20:35 +08:00
# 路由注解事件
2020-12-25 16:53:44 +08:00
炸毛框架提供了一个简易但是高效易用的 HTTP 路由注解,你可以使用路由功能来开发任何 Web 应用微服务、API 接口、中间件等。
::: tip 开发提示
2020-12-25 16:53:44 +08:00
本章节涉及的路由和控制器概念可能和其他传统框架有一些出入,而且炸毛框架非绝对根据 PSR 标准进行开发,目的是使用上一些常见的东西尽可能地灵活和不啰嗦。
:::
2020-12-25 16:53:44 +08:00
## 控制器和路由
Controller 和 Route 为路由注解事件的核心注解事件,其中 Controller 的注解事件为 `@Controller`Route 的注解事件为 `@RequestMapping`
### Controller()
#### 属性
| 类型 | 值 |
| ---------- | ------------------------------- |
| 名称 | `@Controller` |
| 触发前提 | 当路由 url 匹配到时进入触发 |
| 命名空间 | `ZM\Annotation\Http\Controller` |
| 适用位置 | 类 |
| 返回值处理 | 对类注解修饰,无返回值 |
#### 参数
| 参数名称 | 参数范围 | 用途 | 默认 |
| -------- | -------------- | ------------ | ---- |
| prefix | `string`,必需 | 控制器的 url | 空 |
### RequestMapping()
#### 属性
| 类型 | 值 |
| ---------- | ----------------------------------------------------------- |
| 名称 | `@RequestMapping` |
| 触发前提 | 当路由 url 匹配到时进入触发 |
| 命名空间 | `ZM\Annotation\Http\RequestMapping` |
| 适用位置 | 方法 |
| 返回值处理 | 返回类型是 `string` 时,自动调用 HTTP 响应并返回 200 状态码 |
#### 参数
| 参数名称 | 参数范围 | 用途 | 默认 |
| -------------- | ----------------------------------------------------------- | -------------------------- | ------------------------------------------ |
| route | `string`,必需 | 控制器的 url | 空 |
| name | `string` | 路由的名称 | 空 |
| request_method | `array`,限定 `RequestMethod::GET` 等常量 | 限制激活路由的 HTTP 方法 | `[RequestMethod::GET,RequestMethod::POST]` |
| params | `array`,当路由中含有如 `{id}` 类似的动态路由时,会动态改变 | 动态参数的路由参数值的绑定 | `[]` |
#### 函数调用参数
- `$param`:如果路由中存在变量(动态路由),则会把动态路由所匹配的参数放入 `$param` 数组中。
```php
/**
* @RequestMapping(route="/test/{ass}")
*/
public function testName($param) {
return "Your name is ".($param["ass"] ?? "unknown");
}
```
### 路由示例
2020-12-25 16:53:44 +08:00
代码
2020-12-25 16:53:44 +08:00
```php
<?php
namespace Module\Example;
2020-12-25 16:53:44 +08:00
use ZM\Annotation\Http\Controller;
use ZM\Annotation\Http\RequestMapping;
/**
* @Controller("/api")
*/
class Hello {
2020-12-25 16:53:44 +08:00
/**
* @RequestMapping("/index")
2020-12-25 16:53:44 +08:00
*/
public function index(){
ctx()->getResponse()->end("This is API index page"); // 使用上下文获取响应对象
2020-12-25 16:53:44 +08:00
}
/**
* @RequestMapping("/ping")
*/
public function ping(){
return "pong"; // 直接返回字符串
}
}
```
2020-12-25 16:53:44 +08:00
效果
2020-12-25 16:53:44 +08:00
::: tip 效果描述
2020-12-25 16:53:44 +08:00
当访问浏览器的 `http://localhost:20001/api/index` 时,浏览器会返回 `This is API index page`,当访问 `/api/ping` 的 url 时,浏览器会返回 `pong`
2020-12-25 16:53:44 +08:00
```
/ -> 无任何路由
/api/index -> Hello->index
/api/ping -> Hello->ping
```
:::
::: tip 提示
`@Controller``/` 的时候,效果和不写是一样的,`@RequestMapping``/``/index/inside` 等多级路由也是可以的。
:::
2020-12-25 16:53:44 +08:00
### 绑定参数
`@RequestMapping` 中,不仅可以写静态的路由地址,也可以写绑定的参数。例如:`@RequestMapping(route="/index/{name}")`,则访问 `/index/xxx` 的时候,你在函数方法内可以这样获取此参数:
```php
/**
* @RequestMapping("/index/{name}")
*/
public function index($arg) {
return "Your param 'name' is ".$arg["name"];
}
```
## 获取请求参数 GET / POST
2020-12-31 00:28:16 +08:00
炸毛框架支持获取外部 HTTP 请求进来的 GET 和 POST 请求,通过获取 HTTP 请求对象 [Request](/advanced/inside-class/) 即可。对象具体属性和方法点这个链接进去就行。
### 示例
#### 获取 GET
2020-12-31 00:28:16 +08:00
```php
/**
* @RequestMapping("/testUrl")
*/
public function testUrl() {
$get = ctx()->getRequest()->get;
if(isset($get["name"])) return "hello, ".$get["name"];
else return "Unknown name!!";
}
```
2020-12-31 00:28:16 +08:00
#### 获取 POSTx-www-form-urlencoded
2020-12-31 00:28:16 +08:00
```php
/**
* @RequestMapping("/testUrl")
*/
public function testUrl() {
$post = ctx()->getRequest()->post;
if(isset($post["name"])) return "hello, ".$post["name"];
else return "Unknown name!!";
}
```
2020-12-31 00:28:16 +08:00
#### 获取 JSON POST
2020-12-31 00:28:16 +08:00
```php
/**
* @RequestMapping("/testUrl")
*/
public function testUrl() {
$post = ctx()->getRequest()->rawContent();
$json = json_decode($post, true);
if ($json === null) return "Invalid json data!";
if(isset($json["name"])) return "hello, ".$json["name"];
else return "Unknown name!!";
}
```
2020-12-31 00:28:16 +08:00
## 设置路由请求方式
如果想要设置允许请求控制器的 HTTP 请求方式,可以使用方法在控制器中的 `@RequestMapping` 注解配置 `method` 参数,可以是 `GET``POST``PUT`, `PATCH``DELETE``OPTIONS``HEAD` 中的一个或多个。
- 限定 HTTP 方法:`@RequestMapping(method="GET")``@RequestMapping(method={"GET","POST"})`
## 静态文件服务器
框架支持了静态文件的访问。如需使用,则需要先到配置文件中配置相应的 `static_file_server` 参数中 `status``true`
框架分为两种静态文件服务器,一种是全局的静态文件服务器,比如框架部署在 `http://127.0.0.1:20001/` 上通过 HTTP 访问,如果没有访问到 `@RequestMapping` 注解事件注册的路由地址,则会通过 url 自动查找静态文件服务器设置的根路径下面的文件,如果都不存在则会返回 404。
### 配置全局静态文件服务器
我们假设在你写的框架应用的根目录下,有如下文件和内容:
```
resources/html/hello.html (下面是内容)
<html>
<head>
<meta charset="utf-8">
</head>
<body>
框架文档内容太多了,写不完!!!
</body>
</html>
```
然后在 `global.php` 配置文件中静态文件服务器参数为:
```php
/** 静态文件访问 */
$config['static_file_server'] = [
'status' => true,
'document_root' => realpath(__DIR__ . "/../") . '/resources/html',
'document_index' => [
'index.html'
]
];
```
最终,我们通过 `vendor/bin/start server` 等方式,启动框架后,浏览器访问 `http://127.0.0.1:20001/hello.html` 即可获取内容。
### 配置局部静态文件服务器
所涉及的类的命名空间:`use ZM\Http\StaticFileHandler;`
局部静态文件服务器一般用于,比如机器人要发送图片,或者给其他 HTTP 服务提供文件下载的接口时可用。我们假设写了一个图片收集的一个静态文件夹区域,将其中一个子路由当作图片静态目录:
```php
/**
* @RequestMapping("/images/{filename}")
* @param $param
* @return StaticFileHandler
*/
public function staticImage($param) {
Console::info("[下载图片] " . $param["filename"]);
return new StaticFileHandler($param["filename"], "/path/to/your/image_dir/");
}
```
这样当用户访问 `http://框架地址/images/aaa.jpg` 就可以快速地调用此路由下的局部文件服务器功能了。