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,说明您遇到的问题,我们会尽快帮助您解决。