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 Hyperf\Contract\StdoutLoggerInterface;
 5 use Psr\Log\LogLevel;
 6 
 7 return [
 8     'app_name' => env('APP_NAME', 'skeleton'),
 9     'app' => [
10         'name_space' => env('NAME_SPACE', 'App\Controller')
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 App\Service\V1\Auth;
 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 App\Service\V1\Auth;
 4 
 5 use App\Logic\AuthLogic;
 6 use Hyperf\RpcServer\Annotation\RpcService;
 7 
 8 /**
 9  * @RpcService(name="AuthService", protocol="jsonrpc", server="jsonrpc")
10  *
11  * Class AuthService
12  * @package App\Service\V1
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 App\Middleware;
 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 App\Controller\V1;
 6 
 7 use App\Constants\ErrorCode;
 8 
 9 
10 /**
11  * 權限操作模塊
12  * Class AuthController
13  * @package App\Controller\V1
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 App\Request\Auth;
 6 
 7 use Hyperf\Validation\Request\FormRequest;
 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/#/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM