This commit is contained in:
huangzhhui 2020-06-22 00:37:40 +08:00
parent e1a62b0dab
commit 4af32e788a
14 changed files with 491 additions and 32 deletions

View File

@ -36,6 +36,7 @@
- Removed `Hyperf\Di\Listener\LazyLoaderBootApplicationListener`
- Removed method `dispatch(...$params)` from `Hyperf\Dispatcher\AbstractDispatcher`
- Removed mapping for `Hyperf\Contract\NormalizerInterface => Hyperf\Utils\Serializer\SymfonyNormalizer` from `ConfigProvider` in utils.
- Removed the typehint of `$server` parameter of `Hyperf\Contract\OnOpenInterface`、`Hyperf\Contract\OnCloseInterface`、`Hyperf\Contract\OnMessageInterface`、`Hyperf\Contract\OnReceiveInterface`;
## Added
@ -49,11 +50,12 @@
- [#1805](https://github.com/hyperf/hyperf/pull/1805) Added Coroutine Server.
- Changed method `bind(Server $server)` to `bind($server)` in `Hyperf\Contract\ProcessInterface`.
- Changed method `isEnable()` to `isEnable($server)` in `Hyperf\Contract\ProcessInterface`
- Process of config-center, crontab, metric must not run in co-server.
- `Hyperf\AsyncQueue\Environment` only applies to the current coroutine, not process.
- Coroutine Server not support task.
- Process mode of config-center, crontab, metric, comsumers of MQ can not running in coroutine server.
- Change the life-cycle of `Hyperf\AsyncQueue\Environment`, can only applies in the current coroutine, not the whole current process.
- Coroutine Server does not support task mechanism.
- [#1877](https://github.com/hyperf/hyperf/pull/1877) Annotation Inject support typed properties. You can Inject below:
- [#1877](https://github.com/hyperf/hyperf/pull/1877) Support to use typehint of property on PHP 8 to replace `@var` when using `@Inject` annotation, for example:
```
class Example {
/**
@ -62,6 +64,7 @@ class Example {
private ExampleService $exampleService;
}
```
- [#1890](https://github.com/hyperf/hyperf/pull/1890) Added `Hyperf\HttpServer\ResponseEmitter` class to emit any PSR-7 response object with Swoole server, and extracted `Hyperf\Contract\ResponseEmitterInterface`.
- [#1890](https://github.com/hyperf/hyperf/pull/1890) Added `getTrailers()` and `getTrailer(string $key)` and `withTrailer(string $key, $value)` methods for `Hyperf\HttpMessage\Server\Response`.
- [#1920](https://github.com/hyperf/hyperf/pull/1920) Added method `Hyperf\WebSocketServer\Sender::close(int $fd, bool $reset = null)`.
@ -70,19 +73,12 @@ class Example {
- [#1825](https://github.com/hyperf/hyperf/pull/1825) Fixed `TypeError` for `StartServer::execute`.
- [#1854](https://github.com/hyperf/hyperf/pull/1854) Fixed `is_resource` does not works when use `Runtime::enableCoroutine()` privately in filesystem.
- [#1900](https://github.com/hyperf/hyperf/pull/1900) Fixed caster decimal does not work.
- [#1917](https://github.com/hyperf/hyperf/pull/1917) Fixed bug that `Request::isXmlHttpRequest` does not work.
## Optimized
- [#705](https://github.com/hyperf/hyperf/pull/705) Optimized Http Exception.
- [#1793](https://github.com/hyperf/hyperf/pull/1793) Socket.io server now only dispatch connect/disconnect events in onOpen and onClose. Also upgrade some class members from private to protected, so users can hack them.
- [#1848](https://github.com/hyperf/hyperf/pull/1848) Auto generate rpc client code when server start and the interface is changed.
- [#1863](https://github.com/hyperf/hyperf/pull/1863) Support async-queue stop safely.
- [#1896](https://github.com/hyperf/hyperf/pull/1896) Keys will be merged when different constants use the same code.
- [#1900](https://github.com/hyperf/hyperf/pull/1900) Fixed caster decimal of Model does not work.
- [#1917](https://github.com/hyperf/hyperf/pull/1917) Fixed `Request::isXmlHttpRequest` does not work.
## Changed
- [#705](https://github.com/hyperf/hyperf/pull/705) Uniformed the handling of HTTP exceptions, now unified throwing a `Hyperf\HttpMessage\Exception\HttpException` exception class to replace the way of direct response in `Dispatcher`, also provided an `Hyperf\HttpServer\Exception\Handler\ httptionHandler` ExceptionHandler to handle these HTTP Exception;
- [#1846](https://github.com/hyperf/hyperf/pull/1846) Don't auto change the impl for `Hyperf\Contract\NormalizerInterface` when you require `symfony/serialize`. You can added dependiencies below to use symfony serializer.
```php
use Hyperf\Utils\Serializer\SerializerFactory;
@ -99,3 +95,10 @@ return [
- [#1890](https://github.com/hyperf/hyperf/pull/1890) Removed `Hyperf\Contract\Sendable` interface and all implementations of it.
- [#1905](https://github.com/hyperf/hyperf/pull/1905) Removed config `config/server.php`, you can merge it into `config/config.php`.
## Optimized
- [#1793](https://github.com/hyperf/hyperf/pull/1793) Socket.io server now only dispatch connect/disconnect events in onOpen and onClose. Also upgrade some class members from private to protected, so users can hack them.
- [#1848](https://github.com/hyperf/hyperf/pull/1848) Auto generate rpc client code when server start and the interface is changed.
- [#1863](https://github.com/hyperf/hyperf/pull/1863) Support async-queue stop safely.
- [#1896](https://github.com/hyperf/hyperf/pull/1896) Keys will be merged when different constants use the same code.

View File

@ -1,5 +1,110 @@
# 版本更新记录
# v2.0 - 2020-06-22
## 主要功能
1. 重构 [hyperf/di](https://github.com/hyperf/di) 组件,特别是对 AOP 和注解的优化,在 2.0 版本,该组件使用了一个全新的加载机制来提供 AOP 功能的支持。
1. 对比 1.x 版本来说最显著的一个一个功能就是现在你可以通过 AOP 功能切入任何方式实例化的一个类了,比如说,在 1.x 版本,你只能切入由 DI 容器创建的类,你无法切入一个由 `new` 关键词实例化的类,但在 2.0 版本都可以生效了。不过仍有一些例外的情况,您仍无法切入那些在启动阶段用来提供 AOP 功能的类;
2. 在 1.x 版本AOP 只能作用于普通的类,无法支持 `Final` 类,但在 2.0 版本您可以这么做了;
3. 在 1.x 版本,您无法在当前类的构造函数中使用 `@Inject``@Value` 注解标记的类成员属性的值,但在 2.0 版本里,您可以这么做了;
4. 在 1.x 版本,只有通过 DI 容器创建的对象才能使 `@Inject``@Value` 注解的功能生效,通过 `new` 关键词创建的对象无法生效,但在 2.0 版本,都可以生效了;
5. 在 1.x 版本,在使用注解时,您必须定义注解的命名空间来指定使用的注解类,但在 2.0 版本下,您可以为任一注解提供一个别名,这样在使用这个注解时可以直接使用别名而无需引入注解类的命名空间。比如您可以直接在任意类属性上标记 `@Inject` 注解而无需编写 `use Hyperf\Di\Annotation\Inject;`
6. 在 1.x 版本,创建的代理类是一个目标类的子类,这样的实现机制会导致一些魔术常量获得的值返回的是代理类子类的信息,而不是目标类的信息,但在 2.0 版本,代理类会与目标类保持一样的类名和代码结构;
7. 在 1.x 版本,当代理类缓存存在时则不会重新生成缓存,就算源代码发生了变化,这样的机制有助于扫描耗时的提升,但与此同时,这也会导致开发阶段的一些不便利,但在 2.0 版本,代理类缓存会根据源代码的变化而自动变化,这一改变会减少很多在开发阶段的心智负担;
8. 为 Aspect 类增加了 `priority` 优先级属性,现在您可以组织多个 Aspect 之间的顺序了;
9. 在 1.x 版本,您只能通过 `@Aspect` 注解类定义一个 Aspect 类,但在 2.0 版本您还可以通过配置文件、ConfigProvider 来定义 Aspect 类;
10. 在 1.x 版本,您在使用到依赖懒加载功能时,必须注册一个 `Hyperf\Di\Listener\LazyLoaderBootApplicationListener` 监听器,但在 2.0 版本,您可以直接使用该功能而无需做任何的注册动作;
11. 增加了 `annotations.scan.class_map` 配置项,通过该配置您可以将任意类替换成您自己的类,而使用时无需做任何的改变;
## 依赖库更新
- 将 `ext-swoole` 升级到了 `>=4.5`;
- 将 `psr/event-dispatcher` 升级到了 `^1.0`;
- 将 `monolog/monolog` 升级到了 `^2.0`;
- 将 `phpstan/phpstan` 升级到了 `^0.12.18`;
- 将 `vlucas/phpdotenv` 升级到了 `^4.0`;
- 将 `symfony/finder` 升级到了 `^5.0`;
- 将 `symfony/event-dispatcher` 升级到了 `^5.0`;
- 将 `symfony/console` 升级到了 `^5.0`;
- 将 `symfony/property-access` 升级到了 `^5.0`;
- 将 `symfony/serializer` 升级到了 `^5.0`;
- 将 `elasticsearch/elasticsearch` 升级到了 `^7.0`;
## 类和方法的变更
- 移除了 `Hyperf\Di\Aop\AstCollector`
- 移除了 `Hyperf\Di\Aop\ProxyClassNameVisitor`
- 移除了 `Hyperf\Di\Listener\LazyLoaderBootApplicationListener`
- 移除了 `Hyperf\Dispatcher\AbstractDispatcher` 类的 `dispatch(...$params)` 方法;
- 移除了 hyperf/utils 组件中 ConfigProvider 中的 `Hyperf\Contract\NormalizerInterface => Hyperf\Utils\Serializer\SymfonyNormalizer` 关系;
- 移除了 `Hyperf\Contract\OnOpenInterface`、`Hyperf\Contract\OnCloseInterface`、`Hyperf\Contract\OnMessageInterface`、`Hyperf\Contract\OnReceiveInterface` 接口中的 `$server` 参数的强类型声明;
## 新增
- [#992](https://github.com/hyperf/hyperf/pull/992) 新增 [hyperf/reactive-x](https://github.com/hyperf/reactive-x) 组件;
- [#1245](https://github.com/hyperf/hyperf/pull/1245) 为 `ExceptionHandler` 新增了注解的定义方式;
- [#1245](https://github.com/hyperf/hyperf/pull/1245) `ExceptionHandler` 新增了 `priority` 优先级属性,通过配置文件或注解方式均可定义优先级;
- [#1819](https://github.com/hyperf/hyperf/pull/1819) 新增 [hyperf/signal](https://github.com/hyperf/signal) 组件;
- [#1844](https://github.com/hyperf/hyperf/pull/1844) 为 [hyperf/model-cache](https://github.com/hyperf/model-cache) 组件中的 `ttl` 属性增加了 `\DateInterval` 类型的支持;
- [#1855](https://github.com/hyperf/hyperf/pull/1855) 连接池新增了 `ConstantFrequency` 恒定频率策略来释放限制的连接;
- [#1871](https://github.com/hyperf/hyperf/pull/1871) 为 Guzzle 增加 `sink` 选项支持;
- [#1805](https://github.com/hyperf/hyperf/pull/1805) 新增 Coroutine Server 协程服务支持;
- 变更了 `Hyperf\Contract\ProcessInterface` 中的 `bind(Server $server)` 方法声明为 `bind($server)`
- 变更了 `Hyperf\Contract\ProcessInterface` 中的 `isEnable()` 方法声明为 `isEnable($server)`
- 配置中心、Crontab、服务监控、消息队列消费者现在可以通过协程模式来运行且在使用协程服务模式时也必须以协程模式来运行
- `Hyperf\AsyncQueue\Environment` 的作用域改为当前协程内,而不是整个进程;
- 协程模式下不再支持 Task 机制;
- [#1877](https://github.com/hyperf/hyperf/pull/1877) 在 PHP 8 下使用 `@Inject` 注解时支持通过成员属性强类型声明来替代 `@var` 声明,如下所示:
```
class Example {
/**
* @Inject
*/
private ExampleService $exampleService;
}
```
- [#1890](https://github.com/hyperf/hyperf/pull/1890) 新增 `Hyperf\HttpServer\ResponseEmitter` 类来响应任意符合 PSR-7 标准的 Response 对象,同时抽象了 `Hyperf\Contract\ResponseEmitterInterface` 契约;
- [#1890](https://github.com/hyperf/hyperf/pull/1890) 为 `Hyperf\HttpMessage\Server\Response` 类新增了 `getTrailers()``getTrailer(string $key)``withTrailer(string $key, $value)` 方法;
- [#1920](https://github.com/hyperf/hyperf/pull/1920) 新增方法 `Hyperf\WebSocketServer\Sender::close(int $fd, bool $reset = null)`.
## 修复
- [#1825](https://github.com/hyperf/hyperf/pull/1825) 修复了 `StartServer::execute``TypeError`
- [#1854](https://github.com/hyperf/hyperf/pull/1854) 修复了在 filesystem 中使用 `Runtime::enableCoroutine()` 时,`is_resource` 不能工作的问题;
- [#1900](https://github.com/hyperf/hyperf/pull/1900) 修复了 `Model` 中的 `asDecimal` 方法类型有可能错误的问题;
- [#1917](https://github.com/hyperf/hyperf/pull/1917) 修复了 `Request::isXmlHttpRequest` 方法无法正常工作的问题;
## 变更
- [#705](https://github.com/hyperf/hyperf/pull/705) 统一了 HTTP 异常的处理方式,现在统一抛出一个 `Hyperf\HttpMessage\Exception\HttpException` 依赖类来替代在 `Dispatcher` 中直接响应的方式,同时提供了 `Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler` 异常处理器来处理该类异常;
- [#1846](https://github.com/hyperf/hyperf/pull/1846) 当您 require 了 `symfony/serializer` 库,不再自动映射 `Hyperf\Contract\NormalizerInterface` 的实现类,您需要手动添加该映射关系,如下:
```php
use Hyperf\Utils\Serializer\SerializerFactory;
use Hyperf\Utils\Serializer\Serializer;
return [
Hyperf\Contract\NormalizerInterface::class => new SerializerFactory(Serializer::class),
];
```
- [#1924](https://github.com/hyperf/hyperf/pull/1924) 重命名 `Hyperf\GrpcClient\BaseClient``simpleRequest, getGrpcClient, clientStreamRequest` 方法名为 `_simpleRequest, _getGrpcClient, _clientStreamRequest`
## 移除
- [#1890](https://github.com/hyperf/hyperf/pull/1890) Removed `Hyperf\Contract\Sendable` interface and all implementations of it.
- [#1905](https://github.com/hyperf/hyperf/pull/1905) Removed config `config/server.php`, you can merge it into `config/config.php`.
## 优化
- [#1793](https://github.com/hyperf/hyperf/pull/1793) Socket.io 服务现在只在 onOpen and onClose 中触发 connect/disconnect 事件,同时将一些类方法从 private 级别调整到了 protected 级别,以便用户可以方便的重写这些方法;
- [#1848](https://github.com/hyperf/hyperf/pull/1848) 当 RPC 客户端对应的 Contract 发生变更时,自动重写生成对应的动态代理客户端类;
- [#1863](https://github.com/hyperf/hyperf/pull/1863) 为 async-queue 组件提供更加安全的停止机制;
- [#1896](https://github.com/hyperf/hyperf/pull/1896) 当在 constants 组件中使用了同样的 code 时keys 会被合并起来;
# v1.1.32 - 2020-05-21
## 修复

View File

@ -4,8 +4,8 @@
| 版本 | 状态 | 积极支持截止时间 | 安全维护截止时间 | 发布或预计发布时间 |
| ---- | -------- | ---------------- | ---------------- | ------------------ |
| 2.0 | 研发中 | / | / | 2020-06-23 |
| 1.1 | 维护中 | 2020-06-23 | 2020-12-31 | |
| 2.0 | 积极支持中 | / | / | 2020-06-22 |
| 1.1 | 安全维护中 | 2020-06-23 | 2020-12-31 | |
| 1.0 | 停止维护 | 2019-10-08 | 2019-12-31 | 2019-06-20 |
* 积极支持将包含常规迭代周期的 BUG 修复、安全问题修复、功能迭代和功能新增;

View File

@ -170,6 +170,23 @@ return [
当您完成了 ExceptionHandler 的配置后,可以通过直接访问一个不存在的路由,如果响应的状态码为 `404` 即可理解为完成了此项配置的修改。
## 移除 DI 懒加载监听器
如果您的项目中有使用到 DI 组件的懒加载功能,此前您需要注册一个 `Hyperf\Di\Listener\LazyLoaderBootApplicationListener` 监听器,而在 2.0 版本,这一监听器被移除了,您可以直接使用该功能,故如果您此前有使用到该功能,您需要在 `config/autoload/listeners.php` 中移除该监听器的注册;
## 绑定 NormalizerInterface 关系
当您使用了 JSONRPC 功能并使用了 `symfony/serializer` 库来提供序列化功能时,由于 2.0 版本不再自动映射 `Hyperf\Contract\NormalizerInterface` 的实现类,所以您需要手动添加该映射关系,如下:
```php
use Hyperf\Utils\Serializer\SerializerFactory;
use Hyperf\Utils\Serializer\Serializer;
return [
Hyperf\Contract\NormalizerInterface::class => new SerializerFactory(Serializer::class),
];
```
## 调整 composer.json 的依赖版本
由于要升级到 2.0 版本的组件,而原来 skeleton 项目默认情况下是依赖 1.1.x 版本的组件的,所以我们需要对依赖的约束条件进行一些调整,将原来所有 Hyperf 组件的依赖 `~1.1.0` 修改为 `~2.0.0`,修改完后需运行 `composer update` 来将依赖项升级到 2.0 版本。

View File

@ -4,16 +4,16 @@
AOP 為 `Aspect Oriented Programming` 的縮寫,意為:`面向切面編程`通過動態代理等技術實現程序功能的統一維護的一種技術。AOP 是 OOP 的延續,也是 Hyperf 中的一個重要內容,是函數式編程的一種衍生範型。利用 AOP 可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發的效率。
用通俗的話來講,就是在 Hyperf 裏可以通過 `切面(Aspect)` 介入到由 [hyperf/di](https://github.com/hyperf/di) 管理的任意類的任意方法的執行流程中去,從而改變或加強原方法的功能,這就是 AOP。
用通俗的話來講,就是在 Hyperf 裏可以通過 `切面(Aspect)` 介入到任意類的任意方法的執行流程中去,從而改變或加強原方法的功能,這就是 AOP。
> 使用 AOP 功能必須使用 [hyperf/di](https://github.com/hyperf/di) 來作為依賴注入容器
> 注意這裏所指的任意類並不是完全意義上的所有類,在 Hyperf 啟動初期用於實現 AOP 功能的類自身不能被切入。
## 介紹
相對於其它框架實現的 AOP 功能的使用方式,我們進一步簡化了該功能的使用不做過細的劃分,僅存在 `環繞(Around)` 一種通用的形式:
- `切面(Aspect)` 為對流程織入的定義類,包括要介入的目標,以及實現對原方法的修改加強處理
- `代理類(ProxyClass)` ,每個被介入的目標類最終都會生成一個代理類,來達到執行 `切面(Aspect)` 方法的目的,而非通過原類
- `代理類(ProxyClass)` ,每個被介入的目標類最終都會生成一個代理類,來達到執行 `切面(Aspect)` 方法的目的
## 定義切面(Aspect)
@ -62,10 +62,50 @@ class FooAspect extends AbstractAspect
> 使用 `@Aspect` 註解時需 `use Hyperf\Di\Annotation\Aspect;` 命名空間;
您也可以通過 `@Aspect` 註解本身的屬性來完成切入目標的配置,通過下面註解的形式可以達到與上面的示例一樣的目的:
```php
<?php
namespace App\Aspect;
use App\Service\SomeClass;
use App\Annotation\SomeAnnotation;
use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\Di\Aop\ProceedingJoinPoint;
/**
* @Aspect(
* classes={
* SomeClass::class,
* "App\Service\SomeClass::someMethod",
* "App\Service\SomeClass::*Method"
* },
* annotations={
* SomeAnnotation::class
* }
* )
*/
class FooAspect extends AbstractAspect
{
public function process(ProceedingJoinPoint $proceedingJoinPoint)
{
// 切面切入後,執行對應的方法會由此來負責
// $proceedingJoinPoint 為連接點,通過該類的 process() 方法調用原方法並獲得結果
// 在調用前進行某些處理
$result = $proceedingJoinPoint->process();
// 在調用後進行某些處理
return $result;
}
}
```
> 注意目前的 AOP 機制尚未能直接切入 trait 的方法,您可通過使用類重寫該方法,並對使用類進行切入。
## 代理類緩存
所有被 AOP 影響的類,都會在 `./runtime/container/proxy/` 文件夾內生成對應的 `代理類緩存`,服務啟動時,如果類所對應的代理類緩存存在,則不會重新生成直接使用緩存,即使 `Aspect` 的切入範圍發生了改變。不存在時,則會自動重新生成新的代理類緩存。
所有被 AOP 影響的類,都會在 `./runtime/container/proxy/` 文件夾內生成對應的 `代理類緩存`是否在啟動時自動生成取決於 `config/config.php` 配置文件中 `scan_cacheable` 配置項的值,默認值為 `false`,如果該配置項為 `true` 則 Hyperf 不會掃描和生成代理類緩存,而是直接以現有的緩存文件作為最終的代理類。如果該配置項為 `false`,則 Hyperf 會在每次啟動應用時掃描註解掃描域並自動的生成對應的代理類緩存,當代碼發生變化時,代理類緩存也會自動的重新生成。
在部署生產環境時,我們可能會希望 Hyperf 提前將所有代理類提前生成,而不是使用時動態的生成,可以通過 `php bin/hyperf.php di:init-proxy` 命令來生成所有代理類,該命令會忽視現有的代理類緩存,全部重新生成。
通常在開發環境下,該值為 `false`,這樣更便於開發調試,而在部署生產環境時,我們可能會希望 Hyperf 提前將所有代理類提前生成,而不是使用時動態的生成,可以通過 `php bin/hyperf.php` 命令來生成所有代理類,然後再通過環境變量 `SCAN_CACHEABLE``true` 修改該配置項的值,以達到啟動時間更短、應用內存佔用更低的目的
基於以上,我們可以將生成代理類的命令和啟動服務的命令結合起來,`vendor/bin/init-proxy.sh && php bin/hyperf.php start` 來達到自動重新生成所有代理類緩存然後啟動服務的目的。
基於以上,如果您使用 Docker 或 Kubernetes 等虛擬化技術來部署您的應用的話,您可以在鏡像構建階段就生成對應的代理類緩存並寫入到鏡像中去,在運行鏡像實例時,可大大減少啟動時間和應用內存

View File

@ -1,5 +1,110 @@
# 版本更新記錄
# v2.0 - 2020-06-22
## 主要功能
1. 重構 [hyperf/di](https://github.com/hyperf/di) 組件,特別是對 AOP 和註解的優化,在 2.0 版本,該組件使用了一個全新的加載機制來提供 AOP 功能的支持。
1. 對比 1.x 版本來説最顯著的一個一個功能就是現在你可以通過 AOP 功能切入任何方式實例化的一個類了,比如説,在 1.x 版本,你只能切入由 DI 容器創建的類,你無法切入一個由 `new` 關鍵詞實例化的類,但在 2.0 版本都可以生效了。不過仍有一些例外的情況,您仍無法切入那些在啟動階段用來提供 AOP 功能的類;
2. 在 1.x 版本AOP 只能作用於普通的類,無法支持 `Final` 類,但在 2.0 版本您可以這麼做了;
3. 在 1.x 版本,您無法在當前類的構造函數中使用 `@Inject``@Value` 註解標記的類成員屬性的值,但在 2.0 版本里,您可以這麼做了;
4. 在 1.x 版本,只有通過 DI 容器創建的對象才能使 `@Inject``@Value` 註解的功能生效,通過 `new` 關鍵詞創建的對象無法生效,但在 2.0 版本,都可以生效了;
5. 在 1.x 版本,在使用註解時,您必須定義註解的命名空間來指定使用的註解類,但在 2.0 版本下,您可以為任一註解提供一個別名,這樣在使用這個註解時可以直接使用別名而無需引入註解類的命名空間。比如您可以直接在任意類屬性上標記 `@Inject` 註解而無需編寫 `use Hyperf\Di\Annotation\Inject;`
6. 在 1.x 版本,創建的代理類是一個目標類的子類,這樣的實現機制會導致一些魔術常量獲得的值返回的是代理類子類的信息,而不是目標類的信息,但在 2.0 版本,代理類會與目標類保持一樣的類名和代碼結構;
7. 在 1.x 版本,當代理類緩存存在時則不會重新生成緩存,就算源代碼發生了變化,這樣的機制有助於掃描耗時的提升,但與此同時,這也會導致開發階段的一些不便利,但在 2.0 版本,代理類緩存會根據源代碼的變化而自動變化,這一改變會減少很多在開發階段的心智負擔;
8. 為 Aspect 類增加了 `priority` 優先級屬性,現在您可以組織多個 Aspect 之間的順序了;
9. 在 1.x 版本,您只能通過 `@Aspect` 註解類定義一個 Aspect 類,但在 2.0 版本您還可以通過配置文件、ConfigProvider 來定義 Aspect 類;
10. 在 1.x 版本,您在使用到依賴懶加載功能時,必須註冊一個 `Hyperf\Di\Listener\LazyLoaderBootApplicationListener` 監聽器,但在 2.0 版本,您可以直接使用該功能而無需做任何的註冊動作;
11. 增加了 `annotations.scan.class_map` 配置項,通過該配置您可以將任意類替換成您自己的類,而使用時無需做任何的改變;
## 依賴庫更新
- 將 `ext-swoole` 升級到了 `>=4.5`;
- 將 `psr/event-dispatcher` 升級到了 `^1.0`;
- 將 `monolog/monolog` 升級到了 `^2.0`;
- 將 `phpstan/phpstan` 升級到了 `^0.12.18`;
- 將 `vlucas/phpdotenv` 升級到了 `^4.0`;
- 將 `symfony/finder` 升級到了 `^5.0`;
- 將 `symfony/event-dispatcher` 升級到了 `^5.0`;
- 將 `symfony/console` 升級到了 `^5.0`;
- 將 `symfony/property-access` 升級到了 `^5.0`;
- 將 `symfony/serializer` 升級到了 `^5.0`;
- 將 `elasticsearch/elasticsearch` 升級到了 `^7.0`;
## 類和方法的變更
- 移除了 `Hyperf\Di\Aop\AstCollector`
- 移除了 `Hyperf\Di\Aop\ProxyClassNameVisitor`
- 移除了 `Hyperf\Di\Listener\LazyLoaderBootApplicationListener`
- 移除了 `Hyperf\Dispatcher\AbstractDispatcher` 類的 `dispatch(...$params)` 方法;
- 移除了 hyperf/utils 組件中 ConfigProvider 中的 `Hyperf\Contract\NormalizerInterface => Hyperf\Utils\Serializer\SymfonyNormalizer` 關係;
- 移除了 `Hyperf\Contract\OnOpenInterface`、`Hyperf\Contract\OnCloseInterface`、`Hyperf\Contract\OnMessageInterface`、`Hyperf\Contract\OnReceiveInterface` 接口中的 `$server` 參數的強類型聲明;
## 新增
- [#992](https://github.com/hyperf/hyperf/pull/992) 新增 [hyperf/reactive-x](https://github.com/hyperf/reactive-x) 組件;
- [#1245](https://github.com/hyperf/hyperf/pull/1245) 為 `ExceptionHandler` 新增了註解的定義方式;
- [#1245](https://github.com/hyperf/hyperf/pull/1245) `ExceptionHandler` 新增了 `priority` 優先級屬性,通過配置文件或註解方式均可定義優先級;
- [#1819](https://github.com/hyperf/hyperf/pull/1819) 新增 [hyperf/signal](https://github.com/hyperf/signal) 組件;
- [#1844](https://github.com/hyperf/hyperf/pull/1844) 為 [hyperf/model-cache](https://github.com/hyperf/model-cache) 組件中的 `ttl` 屬性增加了 `\DateInterval` 類型的支持;
- [#1855](https://github.com/hyperf/hyperf/pull/1855) 連接池新增了 `ConstantFrequency` 恆定頻率策略來釋放限制的連接;
- [#1871](https://github.com/hyperf/hyperf/pull/1871) 為 Guzzle 增加 `sink` 選項支持;
- [#1805](https://github.com/hyperf/hyperf/pull/1805) 新增 Coroutine Server 協程服務支持;
- 變更了 `Hyperf\Contract\ProcessInterface` 中的 `bind(Server $server)` 方法聲明為 `bind($server)`
- 變更了 `Hyperf\Contract\ProcessInterface` 中的 `isEnable()` 方法聲明為 `isEnable($server)`
- 配置中心、Crontab、服務監控、消息隊列消費者現在可以通過協程模式來運行且在使用協程服務模式時也必須以協程模式來運行
- `Hyperf\AsyncQueue\Environment` 的作用域改為當前協程內,而不是整個進程;
- 協程模式下不再支持 Task 機制;
- [#1877](https://github.com/hyperf/hyperf/pull/1877) 在 PHP 8 下使用 `@Inject` 註解時支持通過成員屬性強類型聲明來替代 `@var` 聲明,如下所示:
```
class Example {
/**
* @Inject
*/
private ExampleService $exampleService;
}
```
- [#1890](https://github.com/hyperf/hyperf/pull/1890) 新增 `Hyperf\HttpServer\ResponseEmitter` 類來響應任意符合 PSR-7 標準的 Response 對象,同時抽象了 `Hyperf\Contract\ResponseEmitterInterface` 契約;
- [#1890](https://github.com/hyperf/hyperf/pull/1890) 為 `Hyperf\HttpMessage\Server\Response` 類新增了 `getTrailers()``getTrailer(string $key)``withTrailer(string $key, $value)` 方法;
- [#1920](https://github.com/hyperf/hyperf/pull/1920) 新增方法 `Hyperf\WebSocketServer\Sender::close(int $fd, bool $reset = null)`.
## 修復
- [#1825](https://github.com/hyperf/hyperf/pull/1825) 修復了 `StartServer::execute``TypeError`
- [#1854](https://github.com/hyperf/hyperf/pull/1854) 修復了在 filesystem 中使用 `Runtime::enableCoroutine()` 時,`is_resource` 不能工作的問題;
- [#1900](https://github.com/hyperf/hyperf/pull/1900) 修復了 `Model` 中的 `asDecimal` 方法類型有可能錯誤的問題;
- [#1917](https://github.com/hyperf/hyperf/pull/1917) 修復了 `Request::isXmlHttpRequest` 方法無法正常工作的問題;
## 變更
- [#705](https://github.com/hyperf/hyperf/pull/705) 統一了 HTTP 異常的處理方式,現在統一拋出一個 `Hyperf\HttpMessage\Exception\HttpException` 依賴類來替代在 `Dispatcher` 中直接響應的方式,同時提供了 `Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler` 異常處理器來處理該類異常;
- [#1846](https://github.com/hyperf/hyperf/pull/1846) 當您 require 了 `symfony/serializer` 庫,不再自動映射 `Hyperf\Contract\NormalizerInterface` 的實現類,您需要手動添加該映射關係,如下:
```php
use Hyperf\Utils\Serializer\SerializerFactory;
use Hyperf\Utils\Serializer\Serializer;
return [
Hyperf\Contract\NormalizerInterface::class => new SerializerFactory(Serializer::class),
];
```
- [#1924](https://github.com/hyperf/hyperf/pull/1924) 重命名 `Hyperf\GrpcClient\BaseClient``simpleRequest, getGrpcClient, clientStreamRequest` 方法名為 `_simpleRequest, _getGrpcClient, _clientStreamRequest`
## 移除
- [#1890](https://github.com/hyperf/hyperf/pull/1890) Removed `Hyperf\Contract\Sendable` interface and all implementations of it.
- [#1905](https://github.com/hyperf/hyperf/pull/1905) Removed config `config/server.php`, you can merge it into `config/config.php`.
## 優化
- [#1793](https://github.com/hyperf/hyperf/pull/1793) Socket.io 服務現在只在 onOpen and onClose 中觸發 connect/disconnect 事件,同時將一些類方法從 private 級別調整到了 protected 級別,以便用户可以方便的重寫這些方法;
- [#1848](https://github.com/hyperf/hyperf/pull/1848) 當 RPC 客户端對應的 Contract 發生變更時,自動重寫生成對應的動態代理客户端類;
- [#1863](https://github.com/hyperf/hyperf/pull/1863) 為 async-queue 組件提供更加安全的停止機制;
- [#1896](https://github.com/hyperf/hyperf/pull/1896) 當在 constants 組件中使用了同樣的 code 時keys 會被合併起來;
# v1.1.32 - 2020-05-21
## 修復

View File

@ -4,8 +4,8 @@
| 版本 | 狀態 | 積極支持截止時間 | 安全維護截止時間 | 發佈或預計發佈時間 |
| ---- | -------- | ---------------- | ---------------- | ------------------ |
| 2.0 | 研發中 | / | / | 2020-06-23 |
| 1.1 | 維護中 | 2020-06-23 | 2020-12-31 | |
| 2.0 | 積極支持中 | / | / | 2020-06-22 |
| 1.1 | 安全維護中 | 2020-06-23 | 2020-12-31 | |
| 1.0 | 停止維護 | 2019-10-08 | 2019-12-31 | 2019-06-20 |
* 積極支持將包含常規迭代週期的 BUG 修復、安全問題修復、功能迭代和功能新增;

View File

@ -204,3 +204,8 @@ public function index(RequestInterface $request)
如果安裝了 devtool 組件,可使用 `php bin/hyperf.php describe:routes` 命令獲取路由列表信息,
並且提供 path 可選項,方便獲取單個路由信息,對應的命令 `php bin/hyperf.php describe:routes --path=/foo/bar`
## HTTP 異常
在路由匹配不到路由時,如 `路由找不到(404)`、`請求方法不允許(405)` 等 HTTP 異常Hyperf 會統一拋出一個 `Hyperf\HttpMessage\Exception\HttpException` 異常類的子類,您需要通過 ExceptionHandler 機制來管理這些異常並做對應的響應處理,默認情況下可以直接使用組件提供的 `Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler` 來進行異常捕獲處理,注意這個異常處理器需要您自行配置到 `config/autoload/exceptions.php` 配置文件中去,並保障多個異常處理器之間的順序鏈路是正確的。
當您需要對 `路由找不到(404)`、`請求方法不允許(405)` 等 HTTP 異常情況的響應進行自定義處理時,您可直接根據 `HttpExceptionHandler` 的代碼實現您自己的異常處理器,並配置您自己的異常處理器。關於異常處理器的邏輯和使用説明,可具體查閲 [異常處理](./zh-cn/exception-handler.md)

View File

@ -170,6 +170,23 @@ return [
當您完成了 ExceptionHandler 的配置後,可以通過直接訪問一個不存在的路由,如果響應的狀態碼為 `404` 即可理解為完成了此項配置的修改。
## 移除 DI 懶加載監聽器
如果您的項目中有使用到 DI 組件的懶加載功能,此前您需要註冊一個 `Hyperf\Di\Listener\LazyLoaderBootApplicationListener` 監聽器,而在 2.0 版本,這一監聽器被移除了,您可以直接使用該功能,故如果您此前有使用到該功能,您需要在 `config/autoload/listeners.php` 中移除該監聽器的註冊;
## 綁定 NormalizerInterface 關係
當您使用了 JSONRPC 功能並使用了 `symfony/serializer` 庫來提供序列化功能時,由於 2.0 版本不再自動映射 `Hyperf\Contract\NormalizerInterface` 的實現類,所以您需要手動添加該映射關係,如下:
```php
use Hyperf\Utils\Serializer\SerializerFactory;
use Hyperf\Utils\Serializer\Serializer;
return [
Hyperf\Contract\NormalizerInterface::class => new SerializerFactory(Serializer::class),
];
```
## 調整 composer.json 的依賴版本
由於要升級到 2.0 版本的組件,而原來 skeleton 項目默認情況下是依賴 1.1.x 版本的組件的,所以我們需要對依賴的約束條件進行一些調整,將原來所有 Hyperf 組件的依賴 `~1.1.0` 修改為 `~2.0.0`,修改完後需運行 `composer update` 來將依賴項升級到 2.0 版本。

View File

@ -4,16 +4,16 @@
AOP 為 `Aspect Oriented Programming` 的縮寫,意為:`面向切面程式設計`通過動態代理等技術實現程式功能的統一維護的一種技術。AOP 是 OOP 的延續,也是 Hyperf 中的一個重要內容,是函數語言程式設計的一種衍生範型。利用 AOP 可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程式的可重用性,同時提高了開發的效率。
用通俗的話來講,就是在 Hyperf 裡可以通過 `切面(Aspect)` 介入到由 [hyperf/di](https://github.com/hyperf/di) 管理的任意類的任意方法的執行流程中去,從而改變或加強原方法的功能,這就是 AOP。
用通俗的話來講,就是在 Hyperf 裡可以通過 `切面(Aspect)` 介入到任意類的任意方法的執行流程中去,從而改變或加強原方法的功能,這就是 AOP。
> 使用 AOP 功能必須使用 [hyperf/di](https://github.com/hyperf/di) 來作為依賴注入容器
> 注意這裡所指的任意類並不是完全意義上的所有類,在 Hyperf 啟動初期用於實現 AOP 功能的類自身不能被切入。
## 介紹
相對於其它框架實現的 AOP 功能的使用方式,我們進一步簡化了該功能的使用不做過細的劃分,僅存在 `環繞(Around)` 一種通用的形式:
- `切面(Aspect)` 為對流程織入的定義類,包括要介入的目標,以及實現對原方法的修改加強處理
- `代理類(ProxyClass)` ,每個被介入的目標類最終都會生成一個代理類,來達到執行 `切面(Aspect)` 方法的目的,而非通過原類
- `代理類(ProxyClass)` ,每個被介入的目標類最終都會生成一個代理類,來達到執行 `切面(Aspect)` 方法的目的
## 定義切面(Aspect)
@ -62,10 +62,50 @@ class FooAspect extends AbstractAspect
> 使用 `@Aspect` 註解時需 `use Hyperf\Di\Annotation\Aspect;` 名稱空間;
您也可以通過 `@Aspect` 註解本身的屬性來完成切入目標的配置,通過下面註解的形式可以達到與上面的示例一樣的目的:
```php
<?php
namespace App\Aspect;
use App\Service\SomeClass;
use App\Annotation\SomeAnnotation;
use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\Di\Aop\ProceedingJoinPoint;
/**
* @Aspect(
* classes={
* SomeClass::class,
* "App\Service\SomeClass::someMethod",
* "App\Service\SomeClass::*Method"
* },
* annotations={
* SomeAnnotation::class
* }
* )
*/
class FooAspect extends AbstractAspect
{
public function process(ProceedingJoinPoint $proceedingJoinPoint)
{
// 切面切入後,執行對應的方法會由此來負責
// $proceedingJoinPoint 為連線點,通過該類的 process() 方法呼叫原方法並獲得結果
// 在呼叫前進行某些處理
$result = $proceedingJoinPoint->process();
// 在呼叫後進行某些處理
return $result;
}
}
```
> 注意目前的 AOP 機制尚未能直接切入 trait 的方法,您可通過使用類重寫該方法,並對使用類進行切入。
## 代理類快取
所有被 AOP 影響的類,都會在 `./runtime/container/proxy/` 資料夾內生成對應的 `代理類快取`,服務啟動時,如果類所對應的代理類快取存在,則不會重新生成直接使用快取,即使 `Aspect` 的切入範圍發生了改變。不存在時,則會自動重新生成新的代理類快取。
所有被 AOP 影響的類,都會在 `./runtime/container/proxy/` 資料夾內生成對應的 `代理類快取`是否在啟動時自動生成取決於 `config/config.php` 配置檔案中 `scan_cacheable` 配置項的值,預設值為 `false`,如果該配置項為 `true` 則 Hyperf 不會掃描和生成代理類快取,而是直接以現有的快取檔案作為最終的代理類。如果該配置項為 `false`,則 Hyperf 會在每次啟動應用時掃描註解掃描域並自動的生成對應的代理類快取,當代碼發生變化時,代理類快取也會自動的重新生成。
在部署生產環境時,我們可能會希望 Hyperf 提前將所有代理類提前生成,而不是使用時動態的生成,可以通過 `php bin/hyperf.php di:init-proxy` 命令來生成所有代理類,該命令會忽視現有的代理類快取,全部重新生成。
通常在開發環境下,該值為 `false`,這樣更便於開發除錯,而在部署生產環境時,我們可能會希望 Hyperf 提前將所有代理類提前生成,而不是使用時動態的生成,可以通過 `php bin/hyperf.php` 命令來生成所有代理類,然後再通過環境變數 `SCAN_CACHEABLE``true` 修改該配置項的值,以達到啟動時間更短、應用記憶體佔用更低的目的
基於以上,我們可以將生成代理類的命令和啟動服務的命令結合起來,`vendor/bin/init-proxy.sh && php bin/hyperf.php start` 來達到自動重新生成所有代理類快取然後啟動服務的目的。
基於以上,如果您使用 Docker 或 Kubernetes 等虛擬化技術來部署您的應用的話,您可以在映象構建階段就生成對應的代理類快取並寫入到映象中去,在執行映象例項時,可大大減少啟動時間和應用記憶體

View File

@ -1,5 +1,110 @@
# 版本更新記錄
# v2.0 - 2020-06-22
## 主要功能
1. 重構 [hyperf/di](https://github.com/hyperf/di) 元件,特別是對 AOP 和註解的優化,在 2.0 版本,該元件使用了一個全新的載入機制來提供 AOP 功能的支援。
1. 對比 1.x 版本來說最顯著的一個一個功能就是現在你可以通過 AOP 功能切入任何方式例項化的一個類了,比如說,在 1.x 版本,你只能切入由 DI 容器建立的類,你無法切入一個由 `new` 關鍵詞例項化的類,但在 2.0 版本都可以生效了。不過仍有一些例外的情況,您仍無法切入那些在啟動階段用來提供 AOP 功能的類;
2. 在 1.x 版本AOP 只能作用於普通的類,無法支援 `Final` 類,但在 2.0 版本您可以這麼做了;
3. 在 1.x 版本,您無法在當前類的建構函式中使用 `@Inject``@Value` 註解標記的類成員屬性的值,但在 2.0 版本里,您可以這麼做了;
4. 在 1.x 版本,只有通過 DI 容器建立的物件才能使 `@Inject``@Value` 註解的功能生效,通過 `new` 關鍵詞建立的物件無法生效,但在 2.0 版本,都可以生效了;
5. 在 1.x 版本,在使用註解時,您必須定義註解的名稱空間來指定使用的註解類,但在 2.0 版本下,您可以為任一註解提供一個別名,這樣在使用這個註解時可以直接使用別名而無需引入註解類的名稱空間。比如您可以直接在任意類屬性上標記 `@Inject` 註解而無需編寫 `use Hyperf\Di\Annotation\Inject;`
6. 在 1.x 版本,建立的代理類是一個目標類的子類,這樣的實現機制會導致一些魔術常量獲得的值返回的是代理類子類的資訊,而不是目標類的資訊,但在 2.0 版本,代理類會與目標類保持一樣的類名和程式碼結構;
7. 在 1.x 版本,當代理類快取存在時則不會重新生成快取,就算原始碼發生了變化,這樣的機制有助於掃描耗時的提升,但與此同時,這也會導致開發階段的一些不便利,但在 2.0 版本,代理類快取會根據原始碼的變化而自動變化,這一改變會減少很多在開發階段的心智負擔;
8. 為 Aspect 類增加了 `priority` 優先順序屬性,現在您可以組織多個 Aspect 之間的順序了;
9. 在 1.x 版本,您只能通過 `@Aspect` 註解類定義一個 Aspect 類,但在 2.0 版本您還可以通過配置檔案、ConfigProvider 來定義 Aspect 類;
10. 在 1.x 版本,您在使用到依賴懶載入功能時,必須註冊一個 `Hyperf\Di\Listener\LazyLoaderBootApplicationListener` 監聽器,但在 2.0 版本,您可以直接使用該功能而無需做任何的註冊動作;
11. 增加了 `annotations.scan.class_map` 配置項,通過該配置您可以將任意類替換成您自己的類,而使用時無需做任何的改變;
## 依賴庫更新
- 將 `ext-swoole` 升級到了 `>=4.5`;
- 將 `psr/event-dispatcher` 升級到了 `^1.0`;
- 將 `monolog/monolog` 升級到了 `^2.0`;
- 將 `phpstan/phpstan` 升級到了 `^0.12.18`;
- 將 `vlucas/phpdotenv` 升級到了 `^4.0`;
- 將 `symfony/finder` 升級到了 `^5.0`;
- 將 `symfony/event-dispatcher` 升級到了 `^5.0`;
- 將 `symfony/console` 升級到了 `^5.0`;
- 將 `symfony/property-access` 升級到了 `^5.0`;
- 將 `symfony/serializer` 升級到了 `^5.0`;
- 將 `elasticsearch/elasticsearch` 升級到了 `^7.0`;
## 類和方法的變更
- 移除了 `Hyperf\Di\Aop\AstCollector`
- 移除了 `Hyperf\Di\Aop\ProxyClassNameVisitor`
- 移除了 `Hyperf\Di\Listener\LazyLoaderBootApplicationListener`
- 移除了 `Hyperf\Dispatcher\AbstractDispatcher` 類的 `dispatch(...$params)` 方法;
- 移除了 hyperf/utils 元件中 ConfigProvider 中的 `Hyperf\Contract\NormalizerInterface => Hyperf\Utils\Serializer\SymfonyNormalizer` 關係;
- 移除了 `Hyperf\Contract\OnOpenInterface`、`Hyperf\Contract\OnCloseInterface`、`Hyperf\Contract\OnMessageInterface`、`Hyperf\Contract\OnReceiveInterface` 介面中的 `$server` 引數的強型別宣告;
## 新增
- [#992](https://github.com/hyperf/hyperf/pull/992) 新增 [hyperf/reactive-x](https://github.com/hyperf/reactive-x) 元件;
- [#1245](https://github.com/hyperf/hyperf/pull/1245) 為 `ExceptionHandler` 新增了註解的定義方式;
- [#1245](https://github.com/hyperf/hyperf/pull/1245) `ExceptionHandler` 新增了 `priority` 優先順序屬性,通過配置檔案或註解方式均可定義優先順序;
- [#1819](https://github.com/hyperf/hyperf/pull/1819) 新增 [hyperf/signal](https://github.com/hyperf/signal) 元件;
- [#1844](https://github.com/hyperf/hyperf/pull/1844) 為 [hyperf/model-cache](https://github.com/hyperf/model-cache) 元件中的 `ttl` 屬性增加了 `\DateInterval` 型別的支援;
- [#1855](https://github.com/hyperf/hyperf/pull/1855) 連線池新增了 `ConstantFrequency` 恆定頻率策略來釋放限制的連線;
- [#1871](https://github.com/hyperf/hyperf/pull/1871) 為 Guzzle 增加 `sink` 選項支援;
- [#1805](https://github.com/hyperf/hyperf/pull/1805) 新增 Coroutine Server 協程服務支援;
- 變更了 `Hyperf\Contract\ProcessInterface` 中的 `bind(Server $server)` 方法宣告為 `bind($server)`
- 變更了 `Hyperf\Contract\ProcessInterface` 中的 `isEnable()` 方法宣告為 `isEnable($server)`
- 配置中心、Crontab、服務監控、訊息佇列消費者現在可以通過協程模式來執行且在使用協程服務模式時也必須以協程模式來執行
- `Hyperf\AsyncQueue\Environment` 的作用域改為當前協程內,而不是整個程序;
- 協程模式下不再支援 Task 機制;
- [#1877](https://github.com/hyperf/hyperf/pull/1877) 在 PHP 8 下使用 `@Inject` 註解時支援通過成員屬性強型別宣告來替代 `@var` 宣告,如下所示:
```
class Example {
/**
* @Inject
*/
private ExampleService $exampleService;
}
```
- [#1890](https://github.com/hyperf/hyperf/pull/1890) 新增 `Hyperf\HttpServer\ResponseEmitter` 類來響應任意符合 PSR-7 標準的 Response 物件,同時抽象了 `Hyperf\Contract\ResponseEmitterInterface` 契約;
- [#1890](https://github.com/hyperf/hyperf/pull/1890) 為 `Hyperf\HttpMessage\Server\Response` 類新增了 `getTrailers()``getTrailer(string $key)``withTrailer(string $key, $value)` 方法;
- [#1920](https://github.com/hyperf/hyperf/pull/1920) 新增方法 `Hyperf\WebSocketServer\Sender::close(int $fd, bool $reset = null)`.
## 修復
- [#1825](https://github.com/hyperf/hyperf/pull/1825) 修復了 `StartServer::execute``TypeError`
- [#1854](https://github.com/hyperf/hyperf/pull/1854) 修復了在 filesystem 中使用 `Runtime::enableCoroutine()` 時,`is_resource` 不能工作的問題;
- [#1900](https://github.com/hyperf/hyperf/pull/1900) 修復了 `Model` 中的 `asDecimal` 方法型別有可能錯誤的問題;
- [#1917](https://github.com/hyperf/hyperf/pull/1917) 修復了 `Request::isXmlHttpRequest` 方法無法正常工作的問題;
## 變更
- [#705](https://github.com/hyperf/hyperf/pull/705) 統一了 HTTP 異常的處理方式,現在統一丟擲一個 `Hyperf\HttpMessage\Exception\HttpException` 依賴類來替代在 `Dispatcher` 中直接響應的方式,同時提供了 `Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler` 異常處理器來處理該類異常;
- [#1846](https://github.com/hyperf/hyperf/pull/1846) 當您 require 了 `symfony/serializer` 庫,不再自動對映 `Hyperf\Contract\NormalizerInterface` 的實現類,您需要手動新增該對映關係,如下:
```php
use Hyperf\Utils\Serializer\SerializerFactory;
use Hyperf\Utils\Serializer\Serializer;
return [
Hyperf\Contract\NormalizerInterface::class => new SerializerFactory(Serializer::class),
];
```
- [#1924](https://github.com/hyperf/hyperf/pull/1924) 重新命名 `Hyperf\GrpcClient\BaseClient``simpleRequest, getGrpcClient, clientStreamRequest` 方法名為 `_simpleRequest, _getGrpcClient, _clientStreamRequest`
## 移除
- [#1890](https://github.com/hyperf/hyperf/pull/1890) Removed `Hyperf\Contract\Sendable` interface and all implementations of it.
- [#1905](https://github.com/hyperf/hyperf/pull/1905) Removed config `config/server.php`, you can merge it into `config/config.php`.
## 優化
- [#1793](https://github.com/hyperf/hyperf/pull/1793) Socket.io 服務現在只在 onOpen and onClose 中觸發 connect/disconnect 事件,同時將一些類方法從 private 級別調整到了 protected 級別,以便使用者可以方便的重寫這些方法;
- [#1848](https://github.com/hyperf/hyperf/pull/1848) 當 RPC 客戶端對應的 Contract 發生變更時,自動重寫生成對應的動態代理客戶端類;
- [#1863](https://github.com/hyperf/hyperf/pull/1863) 為 async-queue 元件提供更加安全的停止機制;
- [#1896](https://github.com/hyperf/hyperf/pull/1896) 當在 constants 元件中使用了同樣的 code 時keys 會被合併起來;
# v1.1.32 - 2020-05-21
## 修復

View File

@ -4,8 +4,8 @@
| 版本 | 狀態 | 積極支援截止時間 | 安全維護截止時間 | 釋出或預計釋出時間 |
| ---- | -------- | ---------------- | ---------------- | ------------------ |
| 2.0 | 研發中 | / | / | 2020-06-23 |
| 1.1 | 維護中 | 2020-06-23 | 2020-12-31 | |
| 2.0 | 積極支援中 | / | / | 2020-06-22 |
| 1.1 | 安全維護中 | 2020-06-23 | 2020-12-31 | |
| 1.0 | 停止維護 | 2019-10-08 | 2019-12-31 | 2019-06-20 |
* 積極支援將包含常規迭代週期的 BUG 修復、安全問題修復、功能迭代和功能新增;

View File

@ -204,3 +204,8 @@ public function index(RequestInterface $request)
如果安裝了 devtool 元件,可使用 `php bin/hyperf.php describe:routes` 命令獲取路由列表資訊,
並且提供 path 可選項,方便獲取單個路由資訊,對應的命令 `php bin/hyperf.php describe:routes --path=/foo/bar`
## HTTP 異常
在路由匹配不到路由時,如 `路由找不到(404)`、`請求方法不允許(405)` 等 HTTP 異常Hyperf 會統一丟擲一個 `Hyperf\HttpMessage\Exception\HttpException` 異常類的子類,您需要通過 ExceptionHandler 機制來管理這些異常並做對應的響應處理,預設情況下可以直接使用元件提供的 `Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler` 來進行異常捕獲處理,注意這個異常處理器需要您自行配置到 `config/autoload/exceptions.php` 配置檔案中去,並保障多個異常處理器之間的順序鏈路是正確的。
當您需要對 `路由找不到(404)`、`請求方法不允許(405)` 等 HTTP 異常情況的響應進行自定義處理時,您可直接根據 `HttpExceptionHandler` 的程式碼實現您自己的異常處理器,並配置您自己的異常處理器。關於異常處理器的邏輯和使用說明,可具體查閱 [異常處理](./zh-cn/exception-handler.md)

View File

@ -170,6 +170,23 @@ return [
當您完成了 ExceptionHandler 的配置後,可以通過直接訪問一個不存在的路由,如果響應的狀態碼為 `404` 即可理解為完成了此項配置的修改。
## 移除 DI 懶載入監聽器
如果您的專案中有使用到 DI 元件的懶載入功能,此前您需要註冊一個 `Hyperf\Di\Listener\LazyLoaderBootApplicationListener` 監聽器,而在 2.0 版本,這一監聽器被移除了,您可以直接使用該功能,故如果您此前有使用到該功能,您需要在 `config/autoload/listeners.php` 中移除該監聽器的註冊;
## 繫結 NormalizerInterface 關係
當您使用了 JSONRPC 功能並使用了 `symfony/serializer` 庫來提供序列化功能時,由於 2.0 版本不再自動對映 `Hyperf\Contract\NormalizerInterface` 的實現類,所以您需要手動新增該對映關係,如下:
```php
use Hyperf\Utils\Serializer\SerializerFactory;
use Hyperf\Utils\Serializer\Serializer;
return [
Hyperf\Contract\NormalizerInterface::class => new SerializerFactory(Serializer::class),
];
```
## 調整 composer.json 的依賴版本
由於要升級到 2.0 版本的元件,而原來 skeleton 專案預設情況下是依賴 1.1.x 版本的元件的,所以我們需要對依賴的約束條件進行一些調整,將原來所有 Hyperf 元件的依賴 `~1.1.0` 修改為 `~2.0.0`,修改完後需執行 `composer update` 來將依賴項升級到 2.0 版本。