• 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/#/

  • 相关阅读:
    MySQL的事务用法:
    MySQL基本命令(增删改查,check约束)总结:
    (转)nodejs npm国内镜像
    NodeJS学习笔记(三)
    NodeJS学习笔记(二).js
    minimist的用法
    npm link没有效果的问题
    DOM Based XSS介绍
    NodeJS学习笔记(一)
    用Ruby写自动生成Sql语句脚本遇到的问题
  • 原文地址:https://www.cnblogs.com/hld123/p/14760064.html
Copyright © 2020-2023  润新知