Hyperf入门

Hyperf入门

    概述

    摘取一段Hyperf官网上对自己的描述:

    Hyperf将超高速和灵活性作为自己的基因,Hyperspeed + Flexibility = Hyperf

    Hyperf框架初衷是作为一个真正为PHP微服务铺路的框架。

    最近公司的项目,在技术选型上采用hyperf来实现,借此机会我也体验了一把基于微服务的理念来做开发。

    安装

    因为还需要使用到redis、mongodb、mysql,为了方便,我是通过yaml文件来安装的,下面贴出来供大家参考:

 1 version: "3"
 2 
 3 services:
 4   redis:
 5     image: redis:6.2.1
 6     container_name: hyperf-redis
 7     restart: always
 8     privileged: true
 9     # environment:
10     #   - TZ=Asia/Shanghai
11     ports:
12       - "26379:6379"
13     networks:
14       internal:
15         ipv4_address: 172.25.2.2
16   mysql:
17     image: mariadb:10.3.28
18     container_name: hyperf-mysql
19     restart: always
20     privileged: true
21     environment:
22       MYSQL_ROOT_PASSWORD: "123456"
23     ports:
24       - "23306:3306"
25     volumes:
26       - /root/hyperf/data/mysql:/var/lib/mysql:rw
27     networks:
28       internal:
29         ipv4_address: 172.25.2.3
30   mongo:
31     image: mongo:4.4
32     container_name: hyperf-mongo
33     restart: always
34     privileged: true
35     # environment:
36     #   MONGO_INITDB_ROOT_USERNAME: 'root'
37     #   MONGO_INITDB_ROOT_PASSWORD: '123456'
38     ports:
39       - "27017:27017"
40     volumes:
41       - /root/hyperf/data/mongo:/data/db:rw
42     networks:
43       internal:
44         ipv4_address: 172.25.2.4
45   hyperf:
46     image: 569529989/hyperf:7.3-alpine-v3.11-swoole-mongo
47     container_name: hyperf-skeleton
48     privileged: true
49     environment:
50       - APP_PROJECT=hyperf
51       - APP_ENV=test
52     ports:
53       - "29501:9501"
54     volumes:
55       - /root/hyperf/data/project:/data/project
56     networks:
57       internal:
58          ipv4_address: 172.25.2.5
59     tty: true
60     entrypoint:
61       - /bin/sh
62 #    depends_on:
63 #      - mysql
64 #      - mongo
65 #      - redis
66 networks:
67   internal:
68     driver: bridge
69     ipam:
70       config:
71       - subnet: 172.25.2.0/24

      有一点要说明的是:

      因为hyperf官方的镜像:hyperf/hyperf:7.4-alpine-v3.11-swoole,这个PHP镜像中安装的扩展很少,主要是为了减少镜像的大小。

      但是我们日常使用php,会用到很多初始镜像内不存在的扩展,比如我这里还需要用到mongodb扩展。于是我在官方的镜像基础上打的包 +mongo扩展,制作了一个新的镜像。

     目录结构

      1、整体结构

     

     2、配置文件结构

    

     那么是如何读取配置呢?

     config/config.php中

 1 <?php
 2 
 3 declare(strict_types=1);
 4 use HyperfContractStdoutLoggerInterface;
 5 use PsrLogLogLevel;
 6 
 7 return [
 8     'app_name' => env('APP_NAME', 'skeleton'),
 9     'app' => [
10         'name_space' => env('NAME_SPACE', 'AppController')
11     ],
12 ];
13 
14 
15 // 读取配置的其中一种方式为:config('app.name_space')

    如果上面的文件绝对路径为:config/autoload/client.php,那么获取的代码为:config('client.app.name_space')

    3、app的目录结构

    

    微服务

    这里有一个原则:

    所有调用的服务都应该放在 service 里面去调用 ,而不是在控制器里面直接调用 model或者logic,也不是在中间件里面直接调用model或者logic   

     

     下面贴一段示例代码:

 AuthServiceInterface.php
 1 <?php
 2 namespace AppServiceV1Auth;
 3 
 4 
 5 interface AuthServiceInterface
 6 {
 7     // 鉴权
 8     public function checkAccess(string $route, int $uid): array;
 9 
10     // 获取所有定义的路由
11     public function getAllDefRoute(): array;
12 
13     // 系统权限添加入库
14     public function refreshItem(): array;
15 
16     // 获取所有的角色/路由/权限列表
17     public function getItemList(array $data): array;
18 }

    AuthService.php

 1 <?php
 2 
 3 namespace AppServiceV1Auth;
 4 
 5 use AppLogicAuthLogic;
 6 use HyperfRpcServerAnnotationRpcService;
 7 
 8 /**
 9  * @RpcService(name="AuthService", protocol="jsonrpc", server="jsonrpc")
10  *
11  * Class AuthService
12  * @package AppServiceV1
13  */
14 class AuthService implements AuthServiceInterface
15 {
16     // 鉴权
17     public function checkAccess(string $route, int $uid): array
18     {
19         return AuthLogic::checkAccess($route, $uid);
20     }
21 
22     // 角色/权限-增加
23     public function addItem(array $data): array
24     {
25         return AuthLogic::addItem($data);
26     }
27 
28     // 角色/权限-删除
29     public function deleteItem(string $name): array
30     {
31         return AuthLogic::deleteItem($name);
32     }
33 }
34         

   服务的调用,参考下面代码:

 1 <?php
 2 
 3 declare(strict_types=1);
 4 
 5 namespace AppMiddleware;
 6 
 7 class CheckLoginMiddleware implements MiddlewareInterface
 8 {
 9     // ...
10 
11     // 鉴权
12     public function checkAccess($uid, $path)
13     {
14         $authService = new AuthService();
15         $accessRes = $authService->checkAccess($path, $uid);
16         return $accessRes;
17     }
18 }    

    中间件

     config/autoload/middlewares.php中

     

   说明:比如项目的需求是先检查是否有登录权限,才去进行参数校验,就需要把登录中间件放到参数校验中间件前面去。

   表单请求验证

   对于复杂的验证场景,我们可以创建一个 表单请求(FormRequest),表单请求是包含验证逻辑的一个自定义请求类。

   啥也不说了,直接贴代码:

   控制器 AuthController.php中

 1 <?php
 2 
 3 declare(strict_types=1);
 4 
 5 namespace AppControllerV1;
 6 
 7 use AppConstantsErrorCode;
 8 
 9 
10 /**
11  * 权限操作模块
12  * Class AuthController
13  * @package AppControllerV1
14  */
15 class AuthController extends AbstractController
16 {
17     // ...
18 
19     /**
20      * 给角色添加路由/权限
21      * @param AuthChildRequest $validator
22      * @return array
23      */
24     public function addChild(AuthChildRequest $validator)
25     {
26         // 参数校验
27         $validatedData = $validator->validated();
28 
29         // 限流 防止恶意请求
30         $uid = $this->request->getAttribute('uid');
31         $res = $this->rateLimit(__FUNCTION__ . '_' . $uid);
32         if ($res['code'] != 0) {
33             return $res;
34         }
35         // ...  
36 }    

    表单验证类 AuthChildRequest.php

 1 <?php
 2 
 3 declare(strict_types=1);
 4 
 5 namespace AppRequestAuth;
 6 
 7 use HyperfValidationRequestFormRequest;
 8 
 9 class AuthChildRequest extends FormRequest
10 {
11     /**
12      * Determine if the user is authorized to make this request.
13      */
14     public function authorize(): bool
15     {
16         return true;
17     }
18 
19     /**
20      * Get custom attributes for validator errors.
21      */
22     public function attributes(): array
23     {
24         return [
25             'parent' => '角色',
26             'child' => '路由',
27         ];
28     }
29 
30     /**
31      * Get the validation rules that apply to the request.
32      */
33     public function rules(): array
34     {
35         return [
36             'parent' => 'required|string|max:255',
37             'child' => 'required|string', // 多个之间用英文逗号隔开
38         ];
39     }
40 
41     /**
42      * 获取已定义验证规则的错误消息
43      */
44     public function messages(): array
45     {
46         return [
47             'required' => ':attribute必填',
48         ];
49     }
50 }

参考链接:

https://hyperf.wiki/2.1/#/

原文地址:https://www.cnblogs.com/hld123/p/14760064.html