­

Hyperf 1.1.0 正式發布了

  • 2019 年 12 月 17 日
  • 筆記

Hyperf 1.1.0 更新內容比較多,但總的來說框架越來越完善。這次更新新增了 Validation 驗證器 基於 Laravel,同時增加了大量的單側。

v1.1.0

新增

  • #401 新增了 HyperfHttpServerRouterDispatched 對象來儲存解析的路由資訊,在用戶中間件之前便解析完成以便後續的使用,同時也修復了路由裡帶參時中間件失效的問題;
  • #402 新增 @AsyncQueueMessage 註解,通過定義此註解在方法上,表明這個方法的實際運行邏輯是投遞給 Async-Queue 隊列去消費;
  • #418 允許發送 WebSocket 消息到任意的 fd,即使當前的 Worker 進程不持有對應的 fd,框架會自動進行進程間通訊來實現發送;
  • #420 為資料庫模型增加新的事件機制,與 PSR-15 的事件調度器相配合,可以解耦的定義 Listener 來監聽模型事件;
  • #429 #643 新增 Validation 表單驗證器組件,這是一個衍生於 illuminate/validation 的組件,感謝 Laravel 開發組提供如此好用的驗證器組件,;
  • #441 當 Redis 連接處於低使用頻率的情況下自動關閉空閑連接;
  • #478 更好的適配 OpenTracing 協議,同時適配 Jaeger,Jaeger 是一款優秀的開源的端對端分散式調用鏈追蹤系統;
  • #500HyperfHttpServerContractResponseInterface 增加鏈式方法調用支援,解決調用了代理方法的方法後無法再調用原始方法的問題;
  • #523gen:model 命令新增了 table-mapping 選項;
  • #555 新增了一個全局函數 swoole_hook_flags 來獲取由常量 SWOOLE_HOOK_FLAGS 所定義的 Runtime Hook 等級,您可以在 bin/hyperf.php 通過 ! defined('SWOOLE_HOOK_FLAGS') && define('SWOOLE_HOOK_FLAGS', SWOOLE_HOOK_ALL); 的方式來定義該常量,即 Runtime Hook 等級;
  • #596@Inject 註解增加了 required 參數,當您定義 @Inject(required=false) 註解到一個成員屬性上,那麼當該依賴項不存在時也不會拋出 HyperfDiExceptionNotFoundException 異常,而是以默認值 null 來注入, required 參數的默認值為 true,當在構造器注入的情況下,您可以通過對構造器的參數定義為 nullable 來達到同樣的目的;
  • #597 為 AsyncQueue 組件的消費者增加 Concurrent 來控制消費速率;
  • #599 為 AsyncQueue 組件的消費者增加根據當前重試次數來設定該消息的重試等待時長的功能,可以為消息設置階梯式的重試等待;
  • #619 為 Guzzle 客戶端增加 HandlerStackFactory 類,以便更便捷地創建一個 HandlerStack;
  • #620 為 AsyncQueue 組件的消費者增加自動重啟的機制;
  • #629 允許通過配置文件的形式為 Apollo 客戶端定義 clientIp, pullTimeout, intervalTimeout 配置;
  • #647 根據 server 的配置,自動為 TCP Response 追加 eof
  • #648 為 AMQP Consumer 增加 nack 的返回類型,當消費邏輯返回 HyperfAmqpResult::NACK 時抽象消費者會以 basic_nack 方法來響應消息;
  • #654 增加所有 Swoole Event 的默認回調和對應的 Hyperf 事件;

變更

  • #437 HyperfTestingClient 在遇到異常時不再直接拋出異常而是交給 ExceptionHandler 流程處理;
  • #463 簡化了 container.php 文件及優化了註解快取機制;

新的 config/container.php 文件內容如下:

<?php    use HyperfDiContainer;  use HyperfDiDefinitionDefinitionSourceFactory;  use HyperfUtilsApplicationContext;    $container = new Container((new DefinitionSourceFactory(true))());    if (! $container instanceof PsrContainerContainerInterface) {      throw new RuntimeException('The dependency injection container is invalid.');  }  return ApplicationContext::setContainer($container);
  • #486 HyperfHttpMessageServerRequestgetParsedBody 方法現在可以直接處理 JSON 格式的數據了;
  • #523 調整 gen:model 命令生成的模型類名默認為單數,如果表名為複數,則默認生成的類名為單數;
  • #614 #617 調整了 ConfigProvider 類的結構, 同時將 config/dependencies.php 文件移動到了 config/autoload/dependencies.php 內,且文件結構去除了 dependencies 層,此後也意味著您也可以將 dependencies 配置寫到 config/config.php 文件內;

Config Provider 內數據結構的變化: 之前:

'scan' => [      'paths' => [          __DIR__,      ],      'collectors' => [],  ],

現在:

'annotations' => [      'scan' => [          'paths' => [              __DIR__,          ],          'collectors' => [],      ],  ],

增加了一層 annotations,這樣將與配置文件結構一致,不再特殊

  • #630 變更了 HyperfHttpServerCoreMiddleware 類的實例化方式,使用 make() 來替代了 new
  • #631 變更了 AMQP Consumer 的實例化方式,使用 make() 來替代了 new
  • #637 調整了HyperfContractOnMessageInterfaceHyperfContractOnOpenInterface的第一個參數的類型約束, 使用SwooleWebSocketServer替代SwooleServer`;
  • #638 重命名了 db:model 命令為 gen:model 命令,同時增加了一個 Visitor 來優化創建的 $connection 成員屬性,如果要創建的模型類的 $connection 屬性的值與繼承的父類一致,那麼創建的模型類將不會包含此屬性;

移除

  • #401 移除了 HyperfJsonRpcHttpServerFactory, HyperfHttpServerServerFactory, HyperfGrpcServerServerFactory 類;
  • #402 移除了棄用的 AsyncQueue::delay 方法;
  • #563 移除了棄用的 HyperfServerServerInterface::SERVER_TCP 常量,使用 HyperfServerServerInterface::SERVER_BASE 來替代;
  • #602 移除了 HyperfUtilsCoroutineConcurrenttimeout 參數;
  • #612 移除了 RingPHP Handler 里沒有使用到的 $url 變數;
  • #616 #618 移除了 Guzzle 里一些無用的程式碼;

優化

  • #644 優化了註解掃描的流程,分開 appvendor 兩部分來掃描註解,大大減少了用戶的掃描耗時;
  • #653 優化了 Swoole shortname 的檢測邏輯,現在的檢測邏輯更加貼合 Swoole 的實際配置場景,也不只是 swoole.use_shortname = "Off" 才能通過檢測了;

修復

  • #448 修復了當 HTTP Server 或 WebSocket Server 存在時,TCP Server 有可能無法啟動的問題;
  • #623 修復了當傳遞一個 null 值到代理類的方法參數時,方法仍然會獲取方法默認值的問題;

從 舊版 1.0 升級

1.1 升級指南

1.1 版新增了很多的功能,但一些改動也涉及到了對 Skeleton 骨架的調整,以及配置項的結構調整,如果您已經投入了業務使用的項目且是基於官方提供的 Skeleton 項目創建的 1.0 應用項目,那麼可以根據下面的內容點來調整您的骨架項目,如果您是一個新的項目,按照文檔通過 composer create-project hyperf/hyperf-skeleton 命令創建新的項目即可使用新的 skeleton 結構。

升級 Swoole 到 4.4+

1.1 版將最低的 Swoole 版本要求從 4.3+ 提升到了 4.4+,這兩個版本之間有一些使用上的細節問題,Hyperf 已經在較早的版本便已適配了,對於 Hyperf 的用戶而言無需理會這之間的差異,我們提升最低 Swoole 版本要求主要是為了減少我們的歷史負擔,而 Swoole 4.4 作為 Swoole 的 LTS(長期支援版本) 也意味著更加的穩定可靠。

Hyperf 在啟動時會進行 Swoole 版本檢測,但為了更好的統一各處對 Swoole 版本的依賴約束,我們建議您將 composer.json 內對 Swoole 的依賴條件改為 "ext-swoole": ">=4.4"

增加 SWOOLE_HOOK_FLAGS 常量

在應用的入口文件 bin/hyperf.php 以及單測的入口文件 test/bootstrap.php 里增加一行常量定義如下:

! defined('SWOOLE_HOOK_FLAGS') && define('SWOOLE_HOOK_FLAGS', SWOOLE_HOOK_ALL);

參考:入口文件參考 單測入口文件參考

移動 config/dependencies.php 文件並調整文件結構

移動 config/dependencies.phpconfig/autoload/dependencies.php,並去除配置文件中的第一層 dependencies,如下:

1.0 的文件結構:

<?php  // config/dependencies.php 文件    return [      'dependencies' => [          FooInterface::class => Foo::class      ],  ];

1.1 的文件結構:

<?php  // config/autoload/dependencies.php 文件    return [      FooInterface::class => Foo::class  ];

調整 config/container.php 文件的內容

由於 1.1 版本調整了 dependencies.php 文件的位置和結構,所處我們還需要調整一下 config/container.php 文件,以便依賴注入容器能夠正確的運行,與此同時,我們也為 config/container.php 提供了更加簡便的寫法,DefinitionSourceFactory 將很多默認的行為聚合了起來,您只需將 config/container.php 文件的內容更換成下面的內容即可:

默認開啟註解掃描快取功能,可修改 DefinitionSourceFactory 入參的第一個參數來關閉此功能

<?php  /**   * Initial a dependency injection container that implemented PSR-11 and return the container.   */  declare(strict_types=1);    use HyperfDiContainer;  use HyperfDiDefinitionDefinitionSourceFactory;  use HyperfUtilsApplicationContext;  use PsrContainerContainerInterface;    $container = new Container((new DefinitionSourceFactory(true))());  if (! $container instanceof ContainerInterface) {      throw new RuntimeException('The dependency injection container is invalid.');  }  return ApplicationContext::setContainer($container);

調整 WebSocket 控制器

由於 1.1 版本調整了 onMessageonOpen 的入參約束,所以需要手動修改其為 SwooleWebSocketServer,具體程式碼如下

<?php  declare(strict_types=1);    namespace AppController;    use HyperfContractOnMessageInterface;  use HyperfContractOnOpenInterface;  use SwooleHttpRequest;  use SwooleWebsocketFrame;  use SwooleWebSocketServer as WebSocketServer;    class WebSocketController implements OnMessageInterface, OnOpenInterface  {      public function onMessage(WebSocketServer $server, Frame $frame): void      {      }        public function onOpen(WebSocketServer $server, Request $request): void      {      }  }

調整自定義組件的 ConfigProvider

1.0 版本中 scan.path 在 1.1 版本中調整為 annotations.scan.path,您需要修改所有自定義組件的 ConfigProvider 類來適配此變更,如您的自定義組件不涉及到註解掃描的功能配置,則可忽略此調整,如下所示:

1.0 的 ConfigProvider 文件結構:

class ConfigProvider  {        public function __invoke(): array      {          return [              'scan' => [                  'paths' => [                      __DIR__,                  ],              ],          ];      }  }

1.1 的 ConfigProvider 文件結構:

class ConfigProvider  {        public function __invoke(): array      {          return [              'annotations' => [                  'scan' => [                      'paths' => [                          __DIR__,                      ],                  ],              ],          ];      }  }

調整默認的本地化語言

如果您在之前有使用 hyperf/translation 組件,那麼您需要檢查一下 config/autoload/translation.php 文件內的 locale 配置項,如為 zh-CN,則需要改為 zh_CN,在 1.1 版本,我們統一了這個配置的值。

調整 composer.json 的依賴

由於要升級到 1.1 版本的組件,而原來 skeleton 項目默認情況下是依賴 1.0.x 版本的組件的,所以我們需要對依賴的約束條件進行一些調整,將原來所有 Hyperf 組件的依賴 ~1.0.0 修改為 ~1.1.0,修改完後需運行 composer update 來將依賴項升級到 1.1 版本。

必須將所有 Hyperf 依賴都升級到 1.1 版本才可用,因為 1.1 調整了組件適配的 ConfigProvider 機制。

完成升級

至此,1.1 升級即已完成,但由於 Hyperf 的各個底層文件都是可以通過 DI 來實現重寫的,如您重寫了某些本次升級調整到了的框架內部文件,您仍需再根據您的實際情況進行一定的調整。

如您在升級上或升級後遇到任何的問題,請前往 Github Issue 提交您的 issue,說明您遇到的問題,我們會儘快幫助您解決。