2019-03-30 12:48:59 +08:00
|
|
|
|
# 控制器
|
|
|
|
|
|
2019-03-30 20:55:38 +08:00
|
|
|
|
通过控制器来处理 HTTP 请求,需要通过 `配置文件` 或 `注解` 的形式将路由与控制器方法进行绑定,具体请查阅 [路由](zh/route.md) 章节。
|
|
|
|
|
对于 `请求(Request)` 与 `响应(Response)`,Hyperf 提供了 `Hyperf\HttpServer\Contract\RequestInterface` 和 `Hyperf\HttpServer\Contract\ResponseInterface` 方便您获取入参和返回数据,关于 [请求](zh/request.md) 与 [响应](zh/response.md) 的详细内容请查阅对应的章节。
|
2019-03-30 12:48:59 +08:00
|
|
|
|
|
2019-03-30 22:53:32 +08:00
|
|
|
|
## 编写控制器
|
2019-03-30 12:48:59 +08:00
|
|
|
|
|
|
|
|
|
```php
|
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
2019-03-30 20:55:38 +08:00
|
|
|
|
namespace App\Controller;
|
2019-03-30 12:48:59 +08:00
|
|
|
|
|
|
|
|
|
use Hyperf\HttpServer\Contract\RequestInterface;
|
|
|
|
|
use Hyperf\HttpServer\Contract\ResponseInterface;
|
|
|
|
|
|
|
|
|
|
class IndexController
|
|
|
|
|
{
|
2019-06-04 19:41:39 +08:00
|
|
|
|
// 在参数上通过定义 RequestInterface 和 ResponseInterface 来获取相关对象,对象会被依赖注入容器自动注入
|
2019-03-30 12:48:59 +08:00
|
|
|
|
public function index(RequestInterface $request, ResponseInterface $response)
|
|
|
|
|
{
|
2019-03-30 20:55:38 +08:00
|
|
|
|
$target = $request->input('target', 'World');
|
|
|
|
|
return 'Hello ' . $target;
|
2019-03-30 12:48:59 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2019-06-04 19:41:39 +08:00
|
|
|
|
> 我们假设该 `Controller` 已经通过了配置文件的形式定义了路由为 `/`,当然您也可以使用注解路由
|
2019-03-30 18:52:20 +08:00
|
|
|
|
|
2019-03-30 20:55:38 +08:00
|
|
|
|
通过 `cURL` 调用该地址,即可看到返回的内容。
|
2019-03-30 12:48:59 +08:00
|
|
|
|
|
|
|
|
|
```bash
|
2019-03-30 18:52:20 +08:00
|
|
|
|
$ curl http://127.0.0.1:9501/\?target\=Hyperf
|
|
|
|
|
Hello Hyperf.
|
2019-03-30 12:48:59 +08:00
|
|
|
|
```
|
|
|
|
|
|
2019-05-07 22:16:46 +08:00
|
|
|
|
## 避免协程间数据混淆
|
|
|
|
|
|
2019-06-20 15:55:30 +08:00
|
|
|
|
在传统的 PHP-FPM 的框架里,会习惯提供一个 `AbstractController` 或其它命名的 `Controller 抽象父类`,然后定义的 `Controller` 需要基础它用于获取一些请求数据或进行一些返回操作,在 Hyperf 里是 **不能这样做** 的,因为在 Hyperf 内绝大部分的对象包括 `Controller` 都是以 `单例(Singleton)` 形式存在的,这也是为了更好的复用对象,而对于与请求相关的数据在协程下也是需要储存到 `协程上下文(Context)` 内的,所以在编写代码时请务必注意 **不要** 将单个请求相关的数据储存在类属性内,包括非静态属性。
|
2019-05-07 22:16:46 +08:00
|
|
|
|
|
2019-06-20 15:55:30 +08:00
|
|
|
|
当然如果非要通过类属性来储存请求数据的话,也不是没有办法的,我们可以注意到我们获取 `请求(Request)` 与 `响应(Response)` 对象时是通过注入 `Hyperf\HttpServer\Contract\RequestInterface` 和 `Hyperf\HttpServer\Contract\ResponseInterface` 来获取的,那对应的对象不也是个单例吗?这里是如何做到协程安全的呢?就 `RequestInterface` 来举例,对应的 `Hyperf\HttpServer\Request` 对象内部在获取 `PSR-7 请求对象` 时,都是从 `协程上下文(Context)` 获取的,所以实际使用的类仅仅是一个代理类,实际调用的都是从 `协程上下文(Context)` 中获取的。
|