mirror of
https://gitee.com/hyperf/hyperf.git
synced 2024-11-30 10:47:44 +08:00
Merge branch 'master' into pr/1969
This commit is contained in:
commit
9925bb25ae
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@ -9,4 +9,4 @@ community_bridge: # Replace with a single Community Bridge project-name e.g., cl
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: #
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: https://doc.hyperf.io/#/zh/donate
|
||||
custom: https://hyperf.wiki/2.0/#/zh-cn/donate
|
||||
|
@ -7,7 +7,7 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## Before you submit this issue, you has been search all existed issues and search the [documentation](https://doc.hyperf.io)
|
||||
## Before you submit this issue, you has been search all existed issues and search the [documentation](https://hyperf.wiki)
|
||||
- [] I've been search all existed issues
|
||||
- [] I've been read all documentation
|
||||
|
||||
|
2
.php_cs
2
.php_cs
@ -4,7 +4,7 @@ $header = <<<'EOF'
|
||||
This file is part of Hyperf.
|
||||
|
||||
@link https://www.hyperf.io
|
||||
@document https://doc.hyperf.io
|
||||
@document https://hyperf.wiki
|
||||
@contact group@hyperf.io
|
||||
@license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
EOF;
|
||||
|
130
CHANGELOG-2.0.md
130
CHANGELOG-2.0.md
@ -1,15 +1,143 @@
|
||||
# v2.0.1 - TBD
|
||||
# v2.0.6 - TBD
|
||||
|
||||
## Fixed
|
||||
|
||||
- [#2236](https://github.com/hyperf/hyperf/pull/2236) Fixed bug that select node failed when using `loadBalancer` for nacos.
|
||||
- [#2242](https://github.com/hyperf/hyperf/pull/2242) Fixed bug that collect more than once time when using watcher.
|
||||
|
||||
# v2.0.5 - 2020-08-03
|
||||
|
||||
## Added
|
||||
|
||||
- [#2001](https://github.com/hyperf/hyperf/pull/2001) Added `$signature` to init command easily.
|
||||
- [#2204](https://github.com/hyperf/hyperf/pull/2204) Added `$concurrent` for function `parallel`.
|
||||
|
||||
## Fixed
|
||||
|
||||
- [#2210](https://github.com/hyperf/hyperf/pull/2210) Fixed bug that open event won't be executed after handshake right now.
|
||||
- [#2214](https://github.com/hyperf/hyperf/pull/2214) Fixed bug that close event won't be executed when close the connection by websocket server.
|
||||
- [#2218](https://github.com/hyperf/hyperf/pull/2218) Fixed bug that sender does not works for coroutine server.
|
||||
- [#2227](https://github.com/hyperf/hyperf/pull/2227) Fixed context won't be destroyed when accept keepalive connection for co server.
|
||||
|
||||
## Optimized
|
||||
|
||||
- [#2193](https://github.com/hyperf/hyperf/pull/2193) Optimized the scan accuracy for `Hyperf\Watcher\Driver\FindDriver`.
|
||||
- [#2232](https://github.com/hyperf/hyperf/pull/2232) Optimized eager load when the type is `In` or `InRaw` for model-cache.
|
||||
|
||||
# v2.0.4 - 2020-07-27
|
||||
|
||||
## Added
|
||||
|
||||
- [#2144](https://github.com/hyperf/hyperf/pull/2144) Added filed `$result` for `QueryExecuted`.
|
||||
- [#2158](https://github.com/hyperf/hyperf/pull/2158) Added route options to route handler.
|
||||
- [#2162](https://github.com/hyperf/hyperf/pull/2162) Added `Hyperf\Watcher\Driver\FindDriver` for `hyperf/watcher`.
|
||||
- [#2169](https://github.com/hyperf/hyperf/pull/2169) Added `session.options.domain` for `hyperf/session` to change the domain which get from request.
|
||||
- [#2174](https://github.com/hyperf/hyperf/pull/2174) Added `ModelRewriteTimestampsVisitor` to rewrite `$timestamps` based on `created_at` and `updated_at` for Model.
|
||||
- [#2175](https://github.com/hyperf/hyperf/pull/2175) Added `ModelRewriteSoftDeletesVisitor` to insert or remove `SoftDeletes` based on `deleted_at` for Model.
|
||||
- [#2176](https://github.com/hyperf/hyperf/pull/2176) Added `ModelRewriteKeyInfoVisitor` to rewrite `$incrementing` `$primaryKey` and `$keyType` for Model.
|
||||
|
||||
## Fixed
|
||||
|
||||
- [#2149](https://github.com/hyperf/hyperf/pull/2149) Fixed bug that custom processes cannot fetch config from nacos.
|
||||
- [#2159](https://github.com/hyperf/hyperf/pull/2159) Fixed fatal exception caused by exist file when using `gen:migration`.
|
||||
|
||||
## Optimized
|
||||
|
||||
- [#2043](https://github.com/hyperf/hyperf/pull/2043) Throw an exception when none of the scan directories exists.
|
||||
- [#2182](https://github.com/hyperf/hyperf/pull/2182) Don't record the close message when the server is not websocket server.
|
||||
|
||||
# v2.0.3 - 2020-07-20
|
||||
|
||||
## Added
|
||||
|
||||
- [#1554](https://github.com/hyperf/hyperf/pull/1554) Added `hyperf/nacos` component.
|
||||
- [#2082](https://github.com/hyperf/hyperf/pull/2082) Added `SIGINT` listened by `Hyperf\Signal\Handler\WorkerStopHandler`.
|
||||
- [#2097](https://github.com/hyperf/hyperf/pull/2097) Added TencentCloud COS for `hyperf/filesystem`.
|
||||
- [#2122](https://github.com/hyperf/hyperf/pull/2122) Added `\Hyperf\Snowflake\Concern\HasSnowflake` Trait to integrate `hyperf/snowflake` and database models.
|
||||
|
||||
## Fixed
|
||||
|
||||
- [#2017](https://github.com/hyperf/hyperf/pull/2017) Fixed when prometheus using the redis record, an error is reported during the rendering of data due to the change in the number of label.
|
||||
- [#2117](https://github.com/hyperf/hyperf/pull/2117) Fixed `@Inject` will be useless sometimes when using `server:watch`.
|
||||
- [#2123](https://github.com/hyperf/hyperf/pull/2123) Fixed bug that `redis::call` will be recorded twice.
|
||||
- [#2139](https://github.com/hyperf/hyperf/pull/2139) Fixed bug that `ValidationMiddleware` will throw exception in websocket.
|
||||
- [#2140](https://github.com/hyperf/hyperf/pull/2140) Fixed a case where session are not saved when exception occurs.
|
||||
|
||||
## Optimized
|
||||
|
||||
- [#2080](https://github.com/hyperf/hyperf/pull/2080) Optimized the type of `$perPage` from `int` to `?int` for method `Hyperf\Database\Model\Builder::paginate`.
|
||||
- [#2110](https://github.com/hyperf/hyperf/pull/2110) Don't kill `SIGTERM` if the process not exists for `hyperf/watcher`.
|
||||
- [#2116](https://github.com/hyperf/hyperf/pull/2116) Optimized requirement for `hyperf/di`.
|
||||
- [#2121](https://github.com/hyperf/hyperf/pull/2121) Replaced the default `@property` if user redeclare it when using `gen:model`.
|
||||
- [#2129](https://github.com/hyperf/hyperf/pull/2129) Optimized the exception message when the response json encoding failed.
|
||||
|
||||
# v2.0.2 - 2020-07-13
|
||||
|
||||
## Added
|
||||
|
||||
- [#2018](https://github.com/hyperf/hyperf/pull/2018) Make prometheus use redis to store data to support cluster mode
|
||||
|
||||
## Fixed
|
||||
|
||||
- [#1898](https://github.com/hyperf/hyperf/pull/1898) Fixed crontab rule `$min-$max` parsing errors.
|
||||
- [#2037](https://github.com/hyperf/hyperf/pull/2037) Fixed bug that tcp server running in only one coroutine.
|
||||
- [#2051](https://github.com/hyperf/hyperf/pull/2051) Fixed `hyperf.pid` won't be created in coroutine server.
|
||||
- [#2055](https://github.com/hyperf/hyperf/pull/1695) Fixed guzzle auto add `Expect: 100-Continue` header when put a large file.
|
||||
- [#2059](https://github.com/hyperf/hyperf/pull/2059) Fixed redis reconnection bug in socket.io server.
|
||||
- [#2067](https://github.com/hyperf/hyperf/pull/2067) Fixed bug that syntax parse error will cause worker exceptions for `hyperf/watcher`.
|
||||
- [#2085](https://github.com/hyperf/hyperf/pull/2085) Fixed bug in RetryFalsy Annotation that leads to retrying truthy results.
|
||||
- [#2089](https://github.com/hyperf/hyperf/pull/2089) Fixed class of command won't be loaded after `gen:command`.
|
||||
- [#2093](https://github.com/hyperf/hyperf/pull/2093) Fixed type error for command `vendor:publish`.
|
||||
|
||||
## Added
|
||||
|
||||
- [#1860](https://github.com/hyperf/hyperf/pull/1860) Added `OnWorkerExit` callback by default for server.
|
||||
- [#2042](https://github.com/hyperf/hyperf/pull/2042) Added `ScanFileDriver` to watch file changes for `hyperf/watcher`.
|
||||
- [#2054](https://github.com/hyperf/hyperf/pull/2054) Added eager load relation for model-cache.
|
||||
|
||||
## Optimized
|
||||
|
||||
- [#2049](https://github.com/hyperf/hyperf/pull/2049) Optimized stdout when server restart for `hyperf/watcher`.
|
||||
- [#2090](https://github.com/hyperf/hyperf/pull/2090) Adapte original response object for `hyperf/session`.
|
||||
|
||||
## Changed
|
||||
|
||||
- [#2031](https://github.com/hyperf/hyperf/pull/2031) The code of constants only support `int` and `string`.
|
||||
- [#2065](https://github.com/hyperf/hyperf/pull/2065) Changed `Hyperf\WebSocketServer\Sender` which only support `push` and `disconnect`.
|
||||
- [#2100](https://github.com/hyperf/hyperf/pull/2100) Upgrade `doctrine/inflector` to `^2.0` for `hyperf/utils`.
|
||||
|
||||
## Removed
|
||||
|
||||
- [#2065](https://github.com/hyperf/hyperf/pull/2065) Removed methods `send` `sendto` and `close` from `Hyperf\WebSocketServer\Sender`.
|
||||
|
||||
# v2.0.1 - 2020-07-02
|
||||
|
||||
## Added
|
||||
|
||||
- [#1934](https://github.com/hyperf/hyperf/pull/1934) Added command `gen:constant`.
|
||||
- [#1982](https://github.com/hyperf/hyperf/pull/1982) Added watcher component.
|
||||
|
||||
## Fixed
|
||||
|
||||
- [#1952](https://github.com/hyperf/hyperf/pull/1952) Fixed bug that migration will be created although class already exists.
|
||||
- [#1960](https://github.com/hyperf/hyperf/pull/1960) Fixed `Hyperf\HttpServer\ResponseEmitter::isMethodsExists()` method does not works as expected.
|
||||
- [#1961](https://github.com/hyperf/hyperf/pull/1961) Fixed start failed when `config/autoload/aspects.php` does not exists.
|
||||
- [#1964](https://github.com/hyperf/hyperf/pull/1964) Fixed http status code 500 caused by empty body.
|
||||
- [#1965](https://github.com/hyperf/hyperf/pull/1965) Fixed the wrong http code when `initRequestAndResponse` failed.
|
||||
- [#1968](https://github.com/hyperf/hyperf/pull/1968) Fixed aspect does not work as expected after `aspects.php` is edited.
|
||||
- [#1985](https://github.com/hyperf/hyperf/pull/1985) Fixed global_imports do not work when the aliases are not all lowercase letters.
|
||||
- [#1990](https://github.com/hyperf/hyperf/pull/1990) Fixed `@Inject` does not work when the parent class has the same property.
|
||||
- [#2019](https://github.com/hyperf/hyperf/pull/2019) Fixed bug that `gen:model` generate property failed, when used `morphTo` or `where`.
|
||||
- [#2026](https://github.com/hyperf/hyperf/pull/2026) Fixed invalid lazy proxy generation when magic methods are used.
|
||||
|
||||
## Changed
|
||||
|
||||
- [#1986](https://github.com/hyperf/hyperf/pull/1986) Changed exit_code `0` to `SIGTERM` when swoole short name do not set disable.
|
||||
|
||||
## Optimized
|
||||
|
||||
- [#1959](https://github.com/hyperf/hyperf/pull/1959) Make ClassLoader easier to be extended.
|
||||
- [#2002](https://github.com/hyperf/hyperf/pull/2002) Support aop in trait when php version >= `7.3`.
|
||||
|
||||
# v2.0.0 - 2020-06-22
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
[English](./README.md) | 中文
|
||||
|
||||
<p align="center"><a href="https://hyperf.io" target="_blank" rel="noopener noreferrer"><img width="70" src="https://www.hyperf.wiki/logo.png" alt="Hyperf Logo"></a></p>
|
||||
<p align="center"><a href="https://hyperf.io" target="_blank" rel="noopener noreferrer"><img width="70" src="https://cdn.jsdelivr.net/gh/hyperf/hyperf/docs/logo.png" alt="Hyperf Logo"></a></p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/hyperf/hyperf/releases"><img src="https://poser.pugx.org/hyperf/hyperf/v/stable" alt="Stable Version"></a>
|
||||
|
@ -1,6 +1,6 @@
|
||||
English | [中文](./README-CN.md)
|
||||
|
||||
<p align="center"><a href="https://hyperf.io" target="_blank" rel="noopener noreferrer"><img width="70" src="https://www.hyperf.wiki/logo.png" alt="Hyperf Logo"></a></p>
|
||||
<p align="center"><a href="https://hyperf.io" target="_blank" rel="noopener noreferrer"><img width="70" src="https://cdn.jsdelivr.net/gh/hyperf/hyperf/docs/logo.png" alt="Hyperf Logo"></a></p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/hyperf/hyperf/releases"><img src="https://poser.pugx.org/hyperf/hyperf/v/stable" alt="Stable Version"></a>
|
||||
|
@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://doc.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
@ -32,7 +32,7 @@
|
||||
"bandwidth-throttle/token-bucket": "^2.0",
|
||||
"doctrine/annotations": "^1.6",
|
||||
"doctrine/common": "@stable",
|
||||
"doctrine/inflector": "^1.3",
|
||||
"doctrine/inflector": "^2.0",
|
||||
"doctrine/instantiator": "^1.0",
|
||||
"domnikl/statsd": "^3.0.1",
|
||||
"egulias/email-validator": "^2.1",
|
||||
@ -62,13 +62,14 @@
|
||||
"nesbot/carbon": "^2.0",
|
||||
"nikic/fast-route": "^1.3",
|
||||
"nikic/php-parser": "^4.1",
|
||||
"overtrue/flysystem-cos": "^2.0",
|
||||
"overtrue/flysystem-qiniu": "^1.0",
|
||||
"php-amqplib/php-amqplib": "^2.7",
|
||||
"php-di/php-di": "^6.0",
|
||||
"php-di/phpdoc-reader": "^2.0.1",
|
||||
"phpstan/phpstan": "^0.12",
|
||||
"phpstan/phpstan": "^0.12.36",
|
||||
"phpunit/phpunit": "^7.0.0",
|
||||
"predis/predis": "^1.1",
|
||||
"reactivex/rxphp": "^2.0",
|
||||
"roave/better-reflection": "^4.0",
|
||||
"smarty/smarty": "^3.1",
|
||||
"squizlabs/php_codesniffer": "^3.4",
|
||||
@ -82,8 +83,7 @@
|
||||
"symfony/serializer": "^5.0",
|
||||
"twig/twig": "^2.12",
|
||||
"vlucas/phpdotenv": "^4.0",
|
||||
"xxtime/flysystem-aliyun-oss": "^1.5",
|
||||
"reactivex/rxphp": "^2.0"
|
||||
"xxtime/flysystem-aliyun-oss": "^1.5"
|
||||
},
|
||||
"replace": {
|
||||
"hyperf/amqp": "self.version",
|
||||
@ -228,6 +228,7 @@
|
||||
"Hyperf\\Utils\\": "src/utils/src/",
|
||||
"Hyperf\\Validation\\": "src/validation/src/",
|
||||
"Hyperf\\View\\": "src/view/src/",
|
||||
"Hyperf\\Watcher\\": "src/watcher/src/",
|
||||
"Hyperf\\WebSocketClient\\": "src/websocket-client/src/",
|
||||
"Hyperf\\WebSocketServer\\": "src/websocket-server/src/"
|
||||
}
|
||||
@ -298,6 +299,7 @@
|
||||
"HyperfTest\\Utils\\": "src/utils/tests/",
|
||||
"HyperfTest\\Validation\\": "src/validation/tests/",
|
||||
"HyperfTest\\View\\": "src/view/tests/",
|
||||
"HyperfTest\\Watcher\\": "src/watcher/tests/",
|
||||
"HyperfTest\\WebSocketClient\\": "src/websocket-client/tests/"
|
||||
}
|
||||
},
|
||||
@ -372,6 +374,7 @@
|
||||
"Hyperf\\Utils\\ConfigProvider",
|
||||
"Hyperf\\Validation\\ConfigProvider",
|
||||
"Hyperf\\View\\ConfigProvider",
|
||||
"Hyperf\\Watcher\\ConfigProvider",
|
||||
"Hyperf\\WebSocketClient\\ConfigProvider",
|
||||
"Hyperf\\WebSocketServer\\ConfigProvider"
|
||||
]
|
||||
|
1250
docs/en/changelog.md
Normal file
1250
docs/en/changelog.md
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
Hyperf provides you with external configuration support for distributed systems, which is adapted by default:
|
||||
|
||||
- [ctripcorp/apollo](https://github.com/ctripcorp/apollo) An open source project by Ctrip, by [hyper/config-apollo](https://github.com/hyperf/config-apollo) component Provide functional support.
|
||||
- Aliyun provides a free configuration center service [ACM (Application Config Manager)](https://help.aliyun.com/product/59604.html) by [hyper/config-aliyun-acm](https://github.com/hyperf/config-aliyun-acm) component provides feature support.
|
||||
- [ctripcorp/apollo](https://github.com/ctripcorp/apollo) An open source project by Ctrip, by [hyperf/config-apollo](https://github.com/hyperf/config-apollo) component Provide functional support.
|
||||
- Aliyun provides a free configuration center service [ACM (Application Config Manager)](https://help.aliyun.com/product/59604.html) by [hyperf/config-aliyun-acm](https://github.com/hyperf/config-aliyun-acm) component provides feature support.
|
||||
|
||||
## Why use the Configuration Center?
|
||||
|
||||
|
@ -23,6 +23,7 @@ config
|
||||
│ ├── commands.php // Used to manage Custom Command
|
||||
│ ├── consul.php // Used to manage Consul Client
|
||||
│ ├── databases.php // Used to manage Database
|
||||
│ ├── dependencies.php // Used to manage the relationship of dependencies of DI
|
||||
│ ├── devtool.php // Used to manage Dev-Tool
|
||||
│ ├── exceptions.php // Used to manage Exception Handler
|
||||
│ ├── listeners.php // Used to manage Event Listener
|
||||
@ -34,7 +35,6 @@ config
|
||||
│ └── server.php // Used to manage Server
|
||||
├── config.php // Configuration for managing users or frameworks, such as relatively independent configuration can also be placed in the autoload folder
|
||||
├── container.php // Responsible for the initialization of the container, running as a configuration file and eventually returning a Psr\Container\ContainerInterface object
|
||||
├── dependencies.php // Used to manage the relationship of dependencies of DI
|
||||
└── routes.php // Used to manage Routing
|
||||
```
|
||||
|
||||
@ -172,7 +172,7 @@ return [
|
||||
|
||||
## Configuration Center
|
||||
|
||||
Hyperf provides you with external configuration support for distributed systems, by default we offer an open source project by Ctrip namely [ctripcorp/apollo](https://github.com/ctripcorp/apollo), by [hyper/config-apollo](https://github.com/hyperf/config-apollo) component provides functional support.
|
||||
Hyperf provides you with external configuration support for distributed systems, by default we offer an open source project by Ctrip namely [ctripcorp/apollo](https://github.com/ctripcorp/apollo), by [hyperf/config-apollo](https://github.com/hyperf/config-apollo) component provides functional support.
|
||||
Details on the usage of the configuration center are explained in the [Configuration Center](en/config-center.md) chapter.
|
||||
|
||||
|
||||
|
19
docs/en/contribute.md
Normal file
19
docs/en/contribute.md
Normal file
@ -0,0 +1,19 @@
|
||||
# Participation in development
|
||||
|
||||
Hyperf is an open source project. The development of an open source project cannot be without the support of the open source community. If you want to participate in the development of Hyperf, you can beginning by [issues](https://github.com/hyperf/hyperf/issues?page=2&q=is%3Aissue+is%3Aopen), usually with the following steps:
|
||||
|
||||
1. Follow the [issues](https://github.com/hyperf/hyperf/issues?page=2&q=is%3Aissue+is%3Aopen) page, and then replies the comments to help users who ask questions;
|
||||
2. According to [issues](https://github.com/hyperf/hyperf/issues?page=2&q=is%3Aissue+is%3Aopen) page, look for bugs or feature request within your capabilities according to your current understanding of Hyperf, and submit the code to [hyperf/hyperf](https://github.com/hyperf/hyperf) repository in the form of [Pull Request](https://github.com/hyperf/hyperf/pulls);
|
||||
3. Follow the progress and replies of your Pull Request, so as to push your Pull Request into the main repository as soon as possible;
|
||||
4. Code Review the Pull Request submitted by others and give your suggestions and opinions.
|
||||
5. Develop independent functional components according to the needs of others or yourself;
|
||||
6. Persist in and continue to carry out the above steps.
|
||||
|
||||
## Join the Hyperf team
|
||||
|
||||
The Hyperf team is a team that continuously maintains and upgrades the Hyperf project and the ecosystem projects of Hyperf. If you want to join it, you first need to have sufficient and continuous enthusiasm and motivation for Hyperf and open source, because you need to devote a lot of time and energy to Hyperf projects. At the same time, you also need to have enough understanding of the Hyperf project to facilitate the maintenance work. Therefore, we also set a certain threshold for joining the Hyperf team. **You need to have at least 100 commits in the [hyperf/hyperf](https://github.com/hyperf/hyperf) repository, or contribute some functional components to Hyperf, and be nominated by any existing Hyperf team member and get the agreement of over half of the team members.**
|
||||
|
||||
Joining the Hyperf team, you will get benefits including but not limited to the following:
|
||||
1. @hyperf.io E-mail
|
||||
2. [Jetbrains All Products Pack](https://www.jetbrains.com/store/#commercial?billing=yearly) (US $649/year)
|
||||
3. [Github team membership](https://github.com/orgs/hyperf/people)
|
@ -38,7 +38,7 @@ message HiReply {
|
||||
- 使用 protoc 生成示例代码
|
||||
|
||||
```
|
||||
# 使用 linux 包管理工具安装 protoc, 下面以 alpine 为例, 也可以参考 hyper-skeleton 下的 Dockerfile
|
||||
# 使用 linux 包管理工具安装 protoc, 下面以 alpine 为例, 也可以参考 hyperf-skeleton 下的 Dockerfile
|
||||
apk add protobuf
|
||||
|
||||
# 使用 protoc 自动生成代码
|
||||
|
@ -8,4 +8,4 @@ Under `PHP-FPM`, you can get the requested parameters through global variables,
|
||||
|
||||
## Classes obtained through the container are singletons
|
||||
|
||||
Through the dependency injection container, all of the in-process persistence is shared by multiple coroutines, so it cannot contain any data that is unique to the request or unique to the coroutine. This type of data is processed through the coroutine context. Please read the [Dependency Injection] (./en/di.md) and [Coroutine] (./en/coroutine.md) sections carefully.
|
||||
Through the dependency injection container, all of the in-process persistence is shared by multiple coroutines, so it cannot contain any data that is unique to the request or unique to the coroutine. This type of data is processed through the coroutine context. Please read the [Dependency Injection] (en/di.md) and [Coroutine] (en/coroutine.md) sections carefully.
|
@ -9,7 +9,7 @@ The various versions of Dockerfile have been prepared for you in the [hyperf\hyp
|
||||
When you don't want to use Docker as the basis for your running environment, you need to make sure that your operating environment meets the following requirements:
|
||||
|
||||
- PHP >= 7.2
|
||||
- Swoole PHP extension >= 4.4,and Disabled `Short Name`
|
||||
- Swoole PHP extension >= 4.5,and Disabled `Short Name`
|
||||
- OpenSSL PHP extension
|
||||
- JSON PHP extension
|
||||
- PDO PHP extension (If you need to use MySQL Client)
|
||||
@ -36,7 +36,7 @@ Assuming your native environment does not meet the Hyperf environment requiremen
|
||||
|
||||
```
|
||||
# Download and run hyperf/hyperf image,and bind the directory of project with /tmp/skeleton of Host
|
||||
docker run -v /tmp/skeleton:/hyperf-skeleton -p 9501:9501 -it --entrypoint /bin/sh hyperf/hyperf:7.2-alpine-cli
|
||||
docker run -v /tmp/skeleton:/hyperf-skeleton -p 9501:9501 -it --entrypoint /bin/sh hyperf/hyperf:latest
|
||||
|
||||
# After the mirror container is running, install Composer in the container
|
||||
wget https://github.com/composer/composer/releases/download/1.8.6/composer.phar
|
||||
|
19
docs/en/release-planning.md
Normal file
19
docs/en/release-planning.md
Normal file
@ -0,0 +1,19 @@
|
||||
# Release Planning
|
||||
|
||||
## Life cycle
|
||||
|
||||
| Version | Status | End of mainstream support | End of Security-fixes support | Release Date |
|
||||
| ---- | -------- | ---------------- | ---------------- | ------------------ |
|
||||
| 2.0 | Mainstream Support | / | / | 2020-06-22 |
|
||||
| 1.1 | Security Fixes | 2020-06-23 | 2020-12-31 | |
|
||||
| 1.0 | Deprecated | 2019-10-08 | 2019-12-31 | 2019-06-20 |
|
||||
|
||||
* Mainstream support including BUG fixes, security fixes, function upgrade and new functions support in a regular iteration cycles;
|
||||
* Security fixes support only includes the fixes of security issues;
|
||||
* The version that is Deprecated status will not undergo any code changes. Please upgrade to the latest version according to the upgrade guide as soon as possible to get better support;
|
||||
|
||||
|
||||
## Version iteration cycle
|
||||
|
||||
Hyperf adopts an agile development model, with an upgrade plan every week, and releases a version on `Monday (UTC/GMT+08:00)` every week, usually a z version release, or a y version . For the x version, the specific iteration plan and time will be determined according to the actual research results.
|
||||
For the version rules adopted by Hyperf, please refer to the [Versions](en/versions.md) chapter.
|
@ -4,7 +4,7 @@
|
||||
|
||||
# 注册服务
|
||||
|
||||
注册服务可通过 `@RpcService` 注解对一个类进行定义,即为发布这个服务了,目前 Hyperf 仅适配了 JSON RPC 协议,具体内容也可到 [JSON RPC 服务](./en/json-rpc.md) 章节了解详情。
|
||||
注册服务可通过 `@RpcService` 注解对一个类进行定义,即为发布这个服务了,目前 Hyperf 仅适配了 JSON RPC 协议,具体内容也可到 [JSON RPC 服务](en/json-rpc.md) 章节了解详情。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
@ -3,6 +3,13 @@
|
||||
* [About Hyperf](en/README.md)
|
||||
* [Communication](en/communication.md)
|
||||
* [Donate](en/donate.md)
|
||||
* [Contribute](en/contribute.md)
|
||||
|
||||
* Versions
|
||||
|
||||
* [Release Planning](en/release-planning.md)
|
||||
* [Versions](en/versions.md)
|
||||
* [Changelogs](en/changelog.md)
|
||||
|
||||
* Quick Start
|
||||
|
||||
@ -34,6 +41,11 @@
|
||||
* [Paginator](en/paginator.md)
|
||||
* [Command](en/command.md)
|
||||
* [Testing](en/testing.md)
|
||||
* [View](en/view.md)
|
||||
* [Translation](en/translation.md)
|
||||
* [Validaton](en/validation.md)
|
||||
* [Session](en/session.md)
|
||||
* [File System](en/filesystem.md)
|
||||
|
||||
* Database
|
||||
|
||||
@ -45,6 +57,8 @@
|
||||
* [Model Event](en/db/event.md)
|
||||
* [Model Cache](en/db/model-cache.md)
|
||||
* [Migration](en/db/migration.md)
|
||||
* [Mutator](en/db/mutators.md)
|
||||
* [Simple DB](en/db/db.md)
|
||||
|
||||
* Microservice
|
||||
|
||||
@ -56,6 +70,16 @@
|
||||
* [Rate Limit](en/rate-limit.md)
|
||||
* [Configuration Center](en/config-center.md)
|
||||
* [Tracing](en/tracer.md)
|
||||
* [Metric](en/metric.md)
|
||||
* [Retry](en/retry.md)
|
||||
* [Nacos](en/nacos.md)
|
||||
|
||||
* Message Queue
|
||||
|
||||
* [Redis Queue](en/async-queue.md)
|
||||
* [AMQP](en/amqp.md)
|
||||
* [Nats](en/nats.md)
|
||||
* [NSQ](en/nsq.md)
|
||||
|
||||
* Other Components
|
||||
|
||||
@ -65,10 +89,9 @@
|
||||
* [Elasticsearch Client](en/elasticsearch.md)
|
||||
* [Consul Client](en/consul.md)
|
||||
* [ETCD Client](en/etcd.md)
|
||||
* [AMQP](en/amqp.md)
|
||||
* [Async Queue](en/async-queue.md)
|
||||
* [WebSocket Server](en/websocket-server.md)
|
||||
* [WebSocket Client](en/websocket-client.md)
|
||||
* [Socket.io](en/socketio-server.md)
|
||||
* [Custom Process](en/process.md)
|
||||
* [Dev Tool](en/devtool.md)
|
||||
* [Utils](en/utils.md)
|
||||
@ -76,6 +99,11 @@
|
||||
* [Swoole Tracker](en/swoole-tracker.md)
|
||||
* [Crontab](en/crontab.md)
|
||||
* [Task](en/task.md)
|
||||
* [Enum](en/constants.md)
|
||||
* [Snowflake](en/snowflake.md)
|
||||
* [Signal Manager](en/signal.md)
|
||||
* [ReactiveX](en/reactive-x.md)
|
||||
* [Watcher](en/watcher.md)
|
||||
|
||||
* Application Deployment
|
||||
|
||||
@ -91,3 +119,8 @@
|
||||
|
||||
* [Introduction](en/component-guide/intro.md)
|
||||
* [Create a new component](en/component-guide/create.md)
|
||||
|
||||
* Upgrade Guide
|
||||
|
||||
* [1.1 Upgrade Guide](en/upgrade/1.1.md)
|
||||
* [2.0 Upgrade Guide](en/upgrade/2.0.md)
|
12
docs/en/versions.md
Normal file
12
docs/en/versions.md
Normal file
@ -0,0 +1,12 @@
|
||||
# Versions
|
||||
|
||||
## Version Rules
|
||||
|
||||
Hyperf uses the version number rule of `x.y.z` to name each version, such as version 1.2.3, 1 is `x`, 2 is `y`, and 3 is `z`. You can make your update plan for the Hyperf framework according to the version rules.
|
||||
- `x` indicates a major version. When the core of Hyperf undergoes a large number of refactoring changes, or when there are a large number of destructive API changes, it will be released as a version `x`. Generally speaking, version x changes cannot be compared with the previous version x Compatible, but it does not necessarily mean that it is completely incompatible. The specific identification is carried out according to the upgrade guide of the corresponding version.
|
||||
- `y` represents an iterative version of a major function. When some public APIs undergo destructive changes, including changes or deletions of public APIs, which may cause the previous version to be incompatible, it will be released as version `y`.
|
||||
- `z` means a fully compatible repair version. When bug fixes or security fixes are performed on the existing functions of each component, a version `z` will be selected for release. When a BUG causes a function to be completely unusable, it is also possible When fixing this BUG in version `z`, destructive changes were made to the API, but since the functions were completely unavailable before, such changes will not be released in version y. In addition to bug fixes, version `z` may also include some new features or Components, these functions and components will not affect the previous code usage.
|
||||
|
||||
## Upgrade
|
||||
|
||||
When you want to upgrade the Hyperf version, if it is an upgrade to the `x` or `y` versions, please follow the upgrade guide for the corresponding version in the document. If you want to upgrade the `z` version, you can directly execute the `composer update hyperf` command in the root directory of your project to update the dependent packages. We do not recommend that you upgrade the version of a certain component separately, but upgrade all components together to get a more consistent development experience.
|
@ -62,17 +62,17 @@ use Swoole\Websocket\Frame;
|
||||
|
||||
class WebSocketController implements OnMessageInterface, OnOpenInterface, OnCloseInterface
|
||||
{
|
||||
public function onMessage(Server $server, Frame $frame): void
|
||||
public function onMessage($server, Frame $frame): void
|
||||
{
|
||||
$server->push($frame->fd, 'Recv: ' . $frame->data);
|
||||
}
|
||||
|
||||
public function onClose(Server $server, int $fd, int $reactorId): void
|
||||
public function onClose($server, int $fd, int $reactorId): void
|
||||
{
|
||||
var_dump('closed');
|
||||
}
|
||||
|
||||
public function onOpen(Server $server, Request $request): void
|
||||
public function onOpen($server, Request $request): void
|
||||
{
|
||||
$server->push($request->fd, 'Opened');
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify/lib/docsify.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/gh/sy-records/staticfile/js/docsify/docsify.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs/components/prism-php.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify-edit-on-github/index.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
||||
@ -28,7 +28,7 @@
|
||||
window.$docsify = {
|
||||
name: 'Hyperf',
|
||||
repo: 'hyperf/hyperf',
|
||||
homepage: './zh-cn/README.md',
|
||||
homepage: 'zh-cn/README.md',
|
||||
loadSidebar: 'summary.md',
|
||||
loadNavbar: true,
|
||||
fallbackLanguages: ['zh-cn', 'en'],
|
||||
@ -60,7 +60,7 @@
|
||||
'/summary.md': './zh-cn/summary.md'
|
||||
},
|
||||
plugins: [
|
||||
EditOnGithubPlugin.create('https://github.com/hyperf/hyperf/tree/master/docs/')
|
||||
EditOnGithubPlugin.create('https://github.com/hyperf/hyperf/blob/master/docs/')
|
||||
],
|
||||
plantuml: {
|
||||
skin: 'classic',
|
||||
@ -78,7 +78,7 @@
|
||||
}
|
||||
</script>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify-copy-code"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/search.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/gh/sy-records/staticfile/js/docsify/search.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify-plantuml/dist/docsify-plantuml.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/zoom-image.min.js"></script>
|
||||
<script type="text/javascript">var cnzz_protocol = (("https:" == document.location.protocol) ? "https://" : "http://");document.write(unescape("%3Cspan style='display:none;' id='cnzz_stat_icon_1278274447'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "v1.cnzz.com/z_stat.php%3Fid%3D1278274447' type='text/javascript'%3E%3C/script%3E"));</script>
|
||||
|
@ -168,6 +168,10 @@ return [
|
||||
|
||||
首先,我们实现一个用于复制上下文的 `Coroutine` 类。其中 `create()` 方法,可以将父类的上下文复制到子类当中。
|
||||
|
||||
为了避免命名冲突,约定使用 `class_map` 做为文件夹名,后跟要替换的命名空间的文件夹及文件。
|
||||
|
||||
如: `class_map/Hyperf/Utils/Coroutine.php`
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
@ -241,7 +245,7 @@ class Coroutine
|
||||
|
||||
然后,我们实现一个跟 `Hyperf\Utils\Coroutine` 一模一样的对象。其中 `create()` 方法替换成我们上述实现的方法。
|
||||
|
||||
`app/Kernel/ClassMap/Coroutine.php`
|
||||
`class_map/Hyperf/Utils/Coroutine.php`
|
||||
|
||||
```php
|
||||
<?php
|
||||
@ -340,7 +344,7 @@ return [
|
||||
],
|
||||
'class_map' => [
|
||||
// 需要映射的类名 => 类所在的文件地址
|
||||
Coroutine::class => BASE_PATH . '/app/Kernel/ClassMap/Coroutine.php',
|
||||
Coroutine::class => BASE_PATH . '/class_map/Hyperf/Utils/Coroutine.php',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
@ -100,7 +100,7 @@ class FooAspect extends AbstractAspect
|
||||
}
|
||||
```
|
||||
|
||||
> 注意目前的 AOP 机制尚未能直接切入 trait 的方法,您可通过使用类重写该方法,并对使用类进行切入。
|
||||
> 2.0.3 及以上版本已经可以支持切入 Trait,但要求 PHP 版本 >= 7.3。
|
||||
|
||||
## 代理类缓存
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
## 如何提交我的组件?
|
||||
|
||||
如果您开发的协程组件适配了 Hyperf,那么您可以直接对 [hyperf/hyperf](https://github.com/hyperf/hyperf) 项目的 `master` 分支发起您的 `Pull Request`,也就是更改当前页`(./zh-cn/awesome-components.md)`。
|
||||
如果您开发的协程组件适配了 Hyperf,那么您可以直接对 [hyperf/hyperf](https://github.com/hyperf/hyperf) 项目的 `master` 分支发起您的 `Pull Request`,也就是更改当前页`(zh-cn/awesome-components.md)`。
|
||||
|
||||
## 如何适配 Hyperf ?
|
||||
|
||||
@ -34,6 +34,7 @@
|
||||
|
||||
- [hyperf/database](https://github.com/hyperf/database) Hyperf 官方提供的基于 Eloquent 衍生的数据库 ORM,可复用于其它框架
|
||||
- [hyperf/model](https://github.com/hyperf/model) Hyperf 官方提供的基于 [hyperf/database](https://github.com/hyperf/database) 组件的自动模型缓存组件
|
||||
- [reasno/fastmongo](https://github.com/Reasno/fastmongo) 基于 `hyperf/gotask` 实现的协程化 `MongoDB` 客户端
|
||||
|
||||
## 依赖注入容器
|
||||
|
||||
@ -104,6 +105,7 @@
|
||||
- [mix-php/swoolefor](https://github.com/mix-php/swoolefor) 一个由 Mixphp 实现的通用热更新组件
|
||||
- [buexplain/go-watch](https://github.com/buexplain/go-watch) 一个基于 Go 语言实现的通用热更新组件
|
||||
- [remy/nodemon](https://github.com/remy/nodemon) 一个基于 node.js 实现的通用热更新组件
|
||||
- [hyperf/watcher](zh-cn/watcher.md) 适配于 `Hyperf 2.0` 的热更新组件
|
||||
|
||||
> Warning: 请勿于生产环境使用 `热更新/热重载` 功能
|
||||
|
||||
|
@ -1,11 +1,141 @@
|
||||
# 版本更新记录
|
||||
|
||||
# v2.0.5 - 2020-08-03
|
||||
|
||||
## 新增
|
||||
|
||||
- [#2001](https://github.com/hyperf/hyperf/pull/2001) 新增参数 `$signature`,用于简化命令行的初始化工作。
|
||||
- [#2204](https://github.com/hyperf/hyperf/pull/2204) 为方法 `parallel` 增加 `$concurrent` 参数,用于快速设置并发量。
|
||||
|
||||
## 修复
|
||||
|
||||
- [#2210](https://github.com/hyperf/hyperf/pull/2210) 修复 `WebSocket` 握手成功后,不会立马触发 `OnOpen` 事件的 BUG。
|
||||
- [#2214](https://github.com/hyperf/hyperf/pull/2214) 修复 `WebSocket` 主动关闭连接时,不会触发 `OnClose` 事件的 BUG。
|
||||
- [#2218](https://github.com/hyperf/hyperf/pull/2218) 修复在 `协程 Server` 下,`Sender::disconnect` 报错的 BUG。
|
||||
- [#2227](https://github.com/hyperf/hyperf/pull/2227) 修复在 `协程 Server` 下,建立 `keepalive` 连接后,上下文数据无法在请求结束后销毁的 BUG。
|
||||
|
||||
## 优化
|
||||
|
||||
- [#2193](https://github.com/hyperf/hyperf/pull/2193) 优化 `Hyperf\Watcher\Driver\FindDriver`,使其扫描有变动的文件更加精确。
|
||||
- [#2232](https://github.com/hyperf/hyperf/pull/2232) 优化 `model-cache` 的预加载功能,使其支持 `In` 和 `InRaw`。
|
||||
|
||||
# v2.0.4 - 2020-07-27
|
||||
|
||||
## 新增
|
||||
|
||||
- [#2144](https://github.com/hyperf/hyperf/pull/2144) 数据库查询事件 `Hyperf\Database\Events\QueryExecuted` 添加 `$result` 字段。
|
||||
- [#2158](https://github.com/hyperf/hyperf/pull/2158) 路由 `Hyperf\HttpServer\Router\Handler` 中,添加 `$options` 字段。
|
||||
- [#2162](https://github.com/hyperf/hyperf/pull/2162) 热更新组件添加 `Hyperf\Watcher\Driver\FindDriver`。
|
||||
- [#2169](https://github.com/hyperf/hyperf/pull/2169) `Session` 组件新增配置 `session.options.domain`,用于替换 `Request` 中获取的 `domain`。
|
||||
- [#2174](https://github.com/hyperf/hyperf/pull/2174) 模型生成器添加 `ModelRewriteTimestampsVisitor`,用于根据数据库字段 `created_at` 和 `updated_at`, 重写模型字段 `$timestamps`。
|
||||
- [#2175](https://github.com/hyperf/hyperf/pull/2175) 模型生成器添加 `ModelRewriteSoftDeletesVisitor`,用于根据数据库字段 `deleted_at`, 添加或者移除 `SoftDeletes`。
|
||||
- [#2176](https://github.com/hyperf/hyperf/pull/2176) 模型生成器添加 `ModelRewriteKeyInfoVisitor`,用于根据数据库主键,重写模型字段 `$incrementing` `$primaryKey` 和 `$keyType`。
|
||||
|
||||
## 修复
|
||||
|
||||
- [#2149](https://github.com/hyperf/hyperf/pull/2149) 修复自定义进程运行过程中无法从 Nacos 正常更新配置的 BUG。
|
||||
- [#2159](https://github.com/hyperf/hyperf/pull/2159) 修复使用 `gen:migration` 时,由于文件已经存在导致的 `FATAL` 异常。
|
||||
|
||||
## 优化
|
||||
|
||||
- [#2043](https://github.com/hyperf/hyperf/pull/2043) 当 `SCAN` 目录都不存在时,抛出更加友好的异常。
|
||||
- [#2182](https://github.com/hyperf/hyperf/pull/2182) 当使用 `WebSocket` 和 `Http` 服务且 `Http` 接口被访问时,不会记录 `WebSocket` 关闭连接的日志。
|
||||
|
||||
# v2.0.3 - 2020-07-20
|
||||
|
||||
## 新增
|
||||
|
||||
- [#1554](https://github.com/hyperf/hyperf/pull/1554) 新增 `hyperf/nacos` 组件。
|
||||
- [#2082](https://github.com/hyperf/hyperf/pull/2082) 监听器 `Hyperf\Signal\Handler\WorkerStopHandler` 添加信号 `SIGINT` 监听。
|
||||
- [#2097](https://github.com/hyperf/hyperf/pull/2097) `hyperf/filesystem` 新增 TencentCloud COS 支持.
|
||||
- [#2122](https://github.com/hyperf/hyperf/pull/2122) 添加 Trait `\Hyperf\Snowflake\Concern\HasSnowflake` 为模型自动生成雪花算法的主键。
|
||||
|
||||
## 修复
|
||||
|
||||
- [#2017](https://github.com/hyperf/hyperf/pull/2017) 修复 Prometheus 使用 redis 打点时,改变 label 会导致收集报错的 BUG。
|
||||
- [#2117](https://github.com/hyperf/hyperf/pull/2117) 修复使用 `server:watch` 时,注解 `@Inject` 有时会失效的 BUG。
|
||||
- [#2123](https://github.com/hyperf/hyperf/pull/2123) 修复 `tracer` 会记录两次 `Redis 指令` 的 BUG。
|
||||
- [#2139](https://github.com/hyperf/hyperf/pull/2139) 修复 `ValidationMiddleware` 在 `WebSocket` 服务下使用会报错的 BUG。
|
||||
- [#2140](https://github.com/hyperf/hyperf/pull/2140) 修复请求抛出异常时,`Session` 无法保存的 BUG。
|
||||
|
||||
## 优化
|
||||
|
||||
- [#2080](https://github.com/hyperf/hyperf/pull/2080) 方法 `Hyperf\Database\Model\Builder::paginate` 中参数 `$perPage` 的类型从 `int` 更改为 `?int`。
|
||||
- [#2110](https://github.com/hyperf/hyperf/pull/2110) 在使用 `hyperf/watcher` 时,会先检查进程是否存在,如果不存在,才会发送 `SIGTERM` 信号。
|
||||
- [#2116](https://github.com/hyperf/hyperf/pull/2116) 优化组件 `hyperf/di` 的依赖。
|
||||
- [#2121](https://github.com/hyperf/hyperf/pull/2121) 在使用 `gen:model` 时,如果用户自定义了与数据库字段一致的字段时,则会替换对应的 `@property`。
|
||||
- [#2129](https://github.com/hyperf/hyperf/pull/2129) 当 Response Json 格式化失败时,会抛出更加友好的错误提示。
|
||||
|
||||
# v2.0.2 - 2020-07-13
|
||||
|
||||
## 修复
|
||||
|
||||
- [#1898](https://github.com/hyperf/hyperf/pull/1898) 修复定时器规则 `$min-$max` 解析有误的 BUG。
|
||||
- [#2037](https://github.com/hyperf/hyperf/pull/2037) 修复 TCP 服务,连接后共用一个协程,导致 DB 等连接池无法正常回收连接的 BUG。
|
||||
- [#2051](https://github.com/hyperf/hyperf/pull/2051) 修复 `CoroutineServer` 不会生成 `hyperf.pid` 的 BUG。
|
||||
- [#2055](https://github.com/hyperf/hyperf/pull/1695) 修复 `Guzzle` 在传输大数据包时会自动添加头 `Expect: 100-Continue`,导致请求失败的 BUG。
|
||||
- [#2059](https://github.com/hyperf/hyperf/pull/2059) 修复 `SocketIOServer` 中 `Redis` 重连失败的 BUG。
|
||||
- [#2067](https://github.com/hyperf/hyperf/pull/2067) 修复 `hyperf/watcher` 组件 `Syntax` 错误会导致进程异常。
|
||||
- [#2085](https://github.com/hyperf/hyperf/pull/2085) 修复注解 `RetryFalsy` 会导致获得正确的结果后,再次重试。
|
||||
- [#2089](https://github.com/hyperf/hyperf/pull/2089) 修复使用 `gen:command` 后,脚本必须要进行修改,才能被加载到的 BUG。
|
||||
- [#2093](https://github.com/hyperf/hyperf/pull/2093) 修复脚本 `vendor:publish` 没有返回码导致报错的 BUG。
|
||||
|
||||
## 新增
|
||||
|
||||
- [#1860](https://github.com/hyperf/hyperf/pull/1860) 为 `Server` 添加默认的 `OnWorkerExit` 回调。
|
||||
- [#2042](https://github.com/hyperf/hyperf/pull/2042) 为热更新组件,添加文件扫描驱动。
|
||||
- [#2054](https://github.com/hyperf/hyperf/pull/2054) 为模型缓存添加 `Eager Load` 功能。
|
||||
|
||||
## 优化
|
||||
|
||||
- [#2049](https://github.com/hyperf/hyperf/pull/2049) 优化热更新组件的 Stdout 输出。
|
||||
- [#2090](https://github.com/hyperf/hyperf/pull/2090) 为 `hyperf/session` 组件适配非 `Hyperf` 的 `Response`。
|
||||
|
||||
## 变更
|
||||
|
||||
- [#2031](https://github.com/hyperf/hyperf/pull/2031) 常量组件的错误码只支持 `int` 和 `string`。
|
||||
- [#2065](https://github.com/hyperf/hyperf/pull/2065) `WebSocket` 消息发送器 `Hyperf\WebSocketServer\Sender` 支持 `push` 和 `disconnect`。
|
||||
- [#2100](https://github.com/hyperf/hyperf/pull/2100) 组件 `hyperf/utils` 更新依赖 `doctrine/inflector` 版本到 `^2.0`。
|
||||
|
||||
## 移除
|
||||
|
||||
- [#2065](https://github.com/hyperf/hyperf/pull/2065) 移除 `Hyperf\WebSocketServer\Sender` 对方法 `send` `sendto` 和 `close` 的支持,请使用 `push` 和 `disconnect`。
|
||||
|
||||
# v2.0.1 - 2020-07-02
|
||||
|
||||
## 新增
|
||||
|
||||
- [#1934](https://github.com/hyperf/hyperf/pull/1934) 增加脚本 `gen:constant` 用于创建常量类。
|
||||
- [#1982](https://github.com/hyperf/hyperf/pull/1982) 添加热更新组件,文件修改后自动收集注解,自动重启。
|
||||
|
||||
## 修复
|
||||
|
||||
- [#1952](https://github.com/hyperf/hyperf/pull/1952) 修复数据库迁移类存在时,也会生成同类名类,导致类名冲突的 BUG。
|
||||
- [#1960](https://github.com/hyperf/hyperf/pull/1960) 修复 `Hyperf\HttpServer\ResponseEmitter::isMethodsExists()` 判断错误的 BUG。
|
||||
- [#1961](https://github.com/hyperf/hyperf/pull/1961) 修复因文件 `config/autoload/aspects.php` 不存在导致服务无法启动的 BUG。
|
||||
- [#1964](https://github.com/hyperf/hyperf/pull/1964) 修复接口请求时,数据体为空会导致 `500` 错误的 BUG。
|
||||
- [#1965](https://github.com/hyperf/hyperf/pull/1965) 修复 `initRequestAndResponse` 失败后,会导致请求状态码与实际不符的 BUG。
|
||||
- [#1968](https://github.com/hyperf/hyperf/pull/1968) 修复当修改 `aspects.php` 文件后,`Aspect` 无法安装修改后的结果运行的 BUG。
|
||||
- [#1985](https://github.com/hyperf/hyperf/pull/1985) 修复注解全局配置不全为小写时,会导致 `global_imports` 失败的 BUG。
|
||||
- [#1990](https://github.com/hyperf/hyperf/pull/1990) 修复当父类存在与子类一样的成员变量时, `@Inject` 无法正常使用的 BUG。
|
||||
- [#2019](https://github.com/hyperf/hyperf/pull/2019) 修复脚本 `gen:model` 因为使用了 `morphTo` 或 `where` 导致生成对应的 `@property` 失败的 BUG。
|
||||
- [#2026](https://github.com/hyperf/hyperf/pull/2026) 修复当使用了魔术方法时,LazyLoad 代理生成有误的 BUG。
|
||||
|
||||
## 变更
|
||||
|
||||
- [#1986](https://github.com/hyperf/hyperf/pull/1986) 当没有设置正确的 `swoole.use_shortname` 变更脚本 `exit_code` 为 `SIGTERM`。
|
||||
|
||||
## 优化
|
||||
|
||||
- [#1959](https://github.com/hyperf/hyperf/pull/1959) 优化类 `ClassLoader` 可以更容易被用户继承并修改。
|
||||
- [#2002](https://github.com/hyperf/hyperf/pull/2002) 当 `PHP` 版本大于等于 `7.3` 时,支持 `AOP` 切入 `Trait`。
|
||||
|
||||
# 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 功能的类;
|
||||
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 版本,都可以生效了;
|
||||
@ -274,7 +404,7 @@ return [
|
||||
|
||||
## 修复
|
||||
|
||||
- [#1445](https://github.com/hyperf/hyperf/pull/1445) 修复命令 `describe:route` 缺失了带参数的路由;
|
||||
- [#1445](https://github.com/hyperf/hyperf/pull/1445) 修复命令 `describe:routes` 缺失了带参数的路由;
|
||||
- [#1449](https://github.com/hyperf/hyperf/pull/1449) 修复了高基数请求路径的内存溢出的问题;
|
||||
- [#1454](https://github.com/hyperf/hyperf/pull/1454) 修复 Collection 的 `flatten()` 方法因为 `INF` 参数值为 `float` 类型导致无法使用的问题;
|
||||
- [#1458](https://github.com/hyperf/hyperf/pull/1458) 修复了 Guzzle 不支持 Elasticsearch 版本大于 7.0 的问题;
|
||||
|
@ -13,7 +13,7 @@ composer require hyperf/circuit-breaker
|
||||
## 使用熔断器
|
||||
|
||||
熔断器的使用十分简单,只需要加入 `Hyperf\CircuitBreaker\Annotation\CircuitBreaker` 注解,就可以根据规定策略,进行熔断。
|
||||
比如我们需要到另外服务中查询用户列表,用户列表需要关联很多的表,查询效率较低,但平常并发量不高的时候,相应速度还说得过去。一旦并发量激增,就会导致响应速度变慢,并会使对方服务出现慢查。这个时候,我们只需要配置一下熔断超时时间 `timeout` 为 0.05 秒,失败计数 `failCounter` 超过 1 次后熔断,相应 `fallback` 为 `App\Service\UserService` 类的 `searchFallback` 方法。这样当响应超时并触发熔断后,就不会再请求对端的服务了,而是直接将服务降级从当前项目中返回数据,即根据 `fallback` 指定的方法来进行返回。
|
||||
比如我们需要到另外服务中查询用户列表,用户列表需要关联很多的表,查询效率较低,但平常并发量不高的时候,响应速度还说得过去。一旦并发量激增,就会导致响应速度变慢,并会使对方服务出现慢查。这个时候,我们只需要配置一下熔断超时时间 `timeout` 为 0.05 秒,失败计数 `failCounter` 超过 1 次后熔断,相应 `fallback` 为 `App\Service\UserService` 类的 `searchFallback` 方法。这样当响应超时并触发熔断后,就不会再请求对端的服务了,而是直接将服务降级从当前项目中返回数据,即根据 `fallback` 指定的方法来进行返回。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
@ -162,7 +162,6 @@ class FooCommand extends HyperfCommand
|
||||
|
||||
执行 `php bin/hyperf.php foo:hello Hyperf` 我们就能看到输出了 `Hello Hyperf` 了。
|
||||
|
||||
|
||||
## 命令常用配置介绍
|
||||
|
||||
以下代码皆只修改 `configure` 和 `handle` 中的内容。
|
||||
@ -360,4 +359,143 @@ array(2) {
|
||||
|
||||
```
|
||||
|
||||
## 通过 `$signature` 配置命令行
|
||||
|
||||
命令行除了上述配置方法外,还支持使用 `$signature` 配置。
|
||||
|
||||
> 需要 command 版本 >= 2.0.5
|
||||
|
||||
`$signature` 为字符串,分为三部分,分别是 `command` `argument` 和 `option`,如下:
|
||||
|
||||
```
|
||||
command:name {argument?* : The argument description.} {--option=* : The option description.}
|
||||
```
|
||||
|
||||
- `?` 代表 `非必传`。
|
||||
- `*` 代表 `数组`。
|
||||
- `?*` 代表 `非必传的数组`。
|
||||
- `=` 代表 `非 Bool`。
|
||||
|
||||
### 示例
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use Hyperf\Command\Annotation\Command;
|
||||
use Hyperf\Command\Command as HyperfCommand;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
* @Command
|
||||
*/
|
||||
class DebugCommand extends HyperfCommand
|
||||
{
|
||||
/**
|
||||
* @var ContainerInterface
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
protected $signature = 'test:test {id : user_id} {--name= : user_name}';
|
||||
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function configure()
|
||||
{
|
||||
parent::configure();
|
||||
$this->setDescription('Hyperf Demo Command');
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
var_dump($this->input->getArguments());
|
||||
var_dump($this->input->getOptions());
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
# 运行命令
|
||||
|
||||
## 命令行中运行
|
||||
|
||||
```bash
|
||||
php bin/hyperf.php foo
|
||||
```
|
||||
|
||||
## 在 Command 中运行其他命令
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use Hyperf\Command\Command as HyperfCommand;
|
||||
use Hyperf\Command\Annotation\Command;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
* @Command
|
||||
*/
|
||||
class FooCommand extends HyperfCommand
|
||||
{
|
||||
/**
|
||||
* @var ContainerInterface
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
|
||||
parent::__construct('foo');
|
||||
}
|
||||
|
||||
public function configure()
|
||||
{
|
||||
parent::configure();
|
||||
$this->setDescription('foo command');
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$this->call('bar', [
|
||||
'--foo' => 'foo'
|
||||
]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 在非 Command 中运行命令
|
||||
|
||||
```php
|
||||
$command = 'foo';
|
||||
|
||||
$params = ["command" => $command, "--foo" => "foo", "--bar" => "bar"];
|
||||
|
||||
// 可以根据自己的需求, 选择使用的 input/output
|
||||
$input = new ArrayInput($params);
|
||||
$output = new NullOutput();
|
||||
|
||||
/** @var \Psr\Container\ContainerInterface $container */
|
||||
$container = \Hyperf\Utils\ApplicationContext::getContainer();
|
||||
|
||||
/** @var \Symfony\Component\Console\Application $application */
|
||||
$application = $container->get(\Hyperf\Contract\ApplicationInterface::class);
|
||||
$application->setAutoExit(false);
|
||||
|
||||
// 这种方式: 不会暴露出命令执行中的异常, 不会阻止程序返回
|
||||
$exitCode = $application->run($input, $output);
|
||||
|
||||
// 第二种方式: 会暴露异常, 需要自己捕捉和处理运行中的异常, 否则会阻止程序的返回
|
||||
$exitCode = $application->find($command)->run($input, $output);
|
||||
```
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
Hyperf 为您提供了分布式系统的外部化配置支持,默认适配了:
|
||||
|
||||
- 由携程开源的 [ctripcorp/apollo](https://github.com/ctripcorp/apollo),由 [hyper/config-apollo](https://github.com/hyperf/config-apollo) 组件提供功能支持。
|
||||
- 阿里云提供的免费配置中心服务 [应用配置管理(ACM, Application Config Manager)](https://help.aliyun.com/product/59604.html),由 [hyper/config-aliyun-acm](https://github.com/hyperf/config-aliyun-acm) 组件提供功能支持。
|
||||
- 由携程开源的 [ctripcorp/apollo](https://github.com/ctripcorp/apollo),由 [hyperf/config-apollo](https://github.com/hyperf/config-apollo) 组件提供功能支持。
|
||||
- 阿里云提供的免费配置中心服务 [应用配置管理(ACM, Application Config Manager)](https://help.aliyun.com/product/59604.html),由 [hyperf/config-aliyun-acm](https://github.com/hyperf/config-aliyun-acm) 组件提供功能支持。
|
||||
|
||||
## 为什么要使用配置中心?
|
||||
|
||||
|
@ -23,6 +23,7 @@ config
|
||||
│ ├── commands.php // 用于管理自定义命令
|
||||
│ ├── consul.php // 用于管理 Consul 客户端
|
||||
│ ├── databases.php // 用于管理数据库客户端
|
||||
│ ├── dependencies.php // 用于管理 DI 的依赖关系和类对应关系
|
||||
│ ├── devtool.php // 用于管理开发者工具
|
||||
│ ├── exceptions.php // 用于管理异常处理器
|
||||
│ ├── listeners.php // 用于管理事件监听者
|
||||
@ -34,7 +35,6 @@ config
|
||||
│ └── server.php // 用于管理 Server 服务
|
||||
├── config.php // 用于管理用户或框架的配置,如配置相对独立亦可放于 autoload 文件夹内
|
||||
├── container.php // 负责容器的初始化,作为一个配置文件运行并最终返回一个 Psr\Container\ContainerInterface 对象
|
||||
├── dependencies.php // 用于管理 DI 的依赖关系和类对应关系
|
||||
└── routes.php // 用于管理路由
|
||||
```
|
||||
|
||||
@ -68,7 +68,7 @@ return [
|
||||
|
||||
如需要设置守护进程化,可在 `settings` 中增加 `'daemonize' => 1`,执行 `php bin/hyperf.php start`后,程序将转入后台作为守护进程运行
|
||||
|
||||
单独的 Server 配置需要添加在对应 `servers` 的 `settings` 当中,如 `jsonrpc` 协议的 TCP Server 配置启用 EOF 自动分包,和设置 EOF 字符串
|
||||
单独的 Server 配置需要添加在对应 `servers` 的 `settings` 当中,如 `jsonrpc` 协议的 TCP Server 配置启用 EOF 自动分包和设置 EOF 字符串
|
||||
```php
|
||||
<?php
|
||||
|
||||
|
@ -20,7 +20,7 @@ $message = ErrorCode::messages[ErrorCode::SERVER_ERROR] ?? '未知错误';
|
||||
|
||||
```
|
||||
|
||||
但这种实现方式并不友好,每当要查询错误码与对应错误信息时,都要在当前 `Class` 中搜索两次。所以框架提供了基于注解的枚举类。
|
||||
但这种实现方式并不友好,每当要查询错误码与对应错误信息时,都要在当前 `Class` 中搜索两次,所以框架提供了基于注解的枚举类。
|
||||
|
||||
## 安装
|
||||
|
||||
@ -32,6 +32,14 @@ composer require hyperf/constants
|
||||
|
||||
### 定义枚举类
|
||||
|
||||
通过 `gen:constant` 命令可以快速的生成一个枚举类。
|
||||
|
||||
```bash
|
||||
php bin/hyperf.php gen:constant ErrorCode
|
||||
```
|
||||
|
||||
!> 此生成命令仅在 [hyperf/constants](https://github.com/hyperf/constants) 组件版本大于等于 v2.0.1 版本时可用,小于此版本时请手动创建枚举类。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
@ -57,7 +65,6 @@ class ErrorCode extends AbstractConstants
|
||||
*/
|
||||
const SYSTEM_INVALID = 700;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
用户可以使用 `ErrorCode::getMessage(ErrorCode::SERVER_ERROR)` 来获取对应错误信息。
|
||||
@ -88,7 +95,6 @@ class BusinessException extends ServerException
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### 抛出异常
|
||||
@ -112,7 +118,6 @@ class IndexController extends Controller
|
||||
throw new BusinessException(ErrorCode::SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### 可变参数
|
||||
@ -139,7 +144,6 @@ class ErrorCode extends AbstractConstants
|
||||
$message = ErrorCode::getMessage(ErrorCode::PARAMS_INVALID, ['user_id']);
|
||||
|
||||
// 1.2 版本以下 可以使用以下方式,但会在 1.2 版本移除
|
||||
|
||||
$message = ErrorCode::getMessage(ErrorCode::PARAMS_INVALID, 'user_id');
|
||||
```
|
||||
|
||||
@ -153,7 +157,7 @@ $message = ErrorCode::getMessage(ErrorCode::PARAMS_INVALID, 'user_id');
|
||||
composer require hyperf/translation
|
||||
```
|
||||
|
||||
相关配置详见 [国际化](translation.md)
|
||||
相关配置详见 [国际化](zh-cn/translation.md)
|
||||
|
||||
```php
|
||||
<?php
|
||||
@ -180,4 +184,3 @@ class ErrorCode extends AbstractConstants
|
||||
|
||||
$message = ErrorCode::getMessage(ErrorCode::SERVER_ERROR, ['param' => 'user_id']);
|
||||
```
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
Hyperf 是一个开源项目,一个开源项目的发展离不开开源社区的力量支持,如果您希望参与 Hyperf 的开发,可以先从 [issues](https://github.com/hyperf/hyperf/issues?page=2&q=is%3Aissue+is%3Aopen) 开始,通常来说会有以下的一些步骤:
|
||||
|
||||
1. 关注 [issues](https://github.com/hyperf/hyperf/issues?page=2&q=is%3Aissue+is%3Aopen) 的动态,评论回复帮助提出疑问的用户;
|
||||
2. 根据 [issues](https://github.com/hyperf/hyperf/issues?page=2&q=is%3Aissue+is%3Aopen) 的内容,找寻根据自己当前对 Hyperf 的了解程度,去修复力所能及的 BUG 或实现功能,并以 [Pull Request](https://https://github.com/hyperf/pulls) 的形式提交至 [hyperf/hyperf](https://github.com/hyperf/hyperf) 仓库;
|
||||
2. 根据 [issues](https://github.com/hyperf/hyperf/issues?page=2&q=is%3Aissue+is%3Aopen) 的内容,找寻根据自己当前对 Hyperf 的了解程度,去修复力所能及的 BUG 或实现功能,并以 [Pull Request](https://github.com/hyperf/hyperf/pulls) 的形式提交至 [hyperf/hyperf](https://github.com/hyperf/hyperf) 仓库;
|
||||
3. 关注自己提交 Pull Request 的进度和状态,以推动您的 Pull Request 尽快合入主仓库;
|
||||
4. 对其他人提交的 Pull Request 进行 Code Review,并给出您的建议和看法。
|
||||
5. 根据他人或自己的需求,研发独立的功能组件;
|
||||
|
137
docs/zh-cn/db/gen.md
Normal file
137
docs/zh-cn/db/gen.md
Normal file
@ -0,0 +1,137 @@
|
||||
# 模型创建脚本
|
||||
|
||||
Hyperf 提供了创建模型的命令,您可以很方便的根据数据表创建对应模型。命令通过 `AST` 生成模型,所以当您增加了某些方法后,也可以使用脚本方便的重置模型。
|
||||
|
||||
```bash
|
||||
php bin/hyperf.php gen:model table_name
|
||||
```
|
||||
|
||||
## 创建模型
|
||||
|
||||
可选参数如下:
|
||||
|
||||
| 参数 | 类型 | 默认值 | 备注 |
|
||||
| :----------------: | :----: | :-------------------------------: | :-----------------------------------------------: |
|
||||
| --pool | string | `default` | 连接池,脚本会根据当前连接池配置创建 |
|
||||
| --path | string | `app/Model` | 模型路径 |
|
||||
| --force-casts | bool | `false` | 是否强制重置 `casts` 参数 |
|
||||
| --prefix | string | 空字符串 | 表前缀 |
|
||||
| --inheritance | string | `Model` | 父类 |
|
||||
| --uses | string | `Hyperf\DbConnection\Model\Model` | 配合 `inheritance` 使用 |
|
||||
| --refresh-fillable | bool | `false` | 是否刷新 `fillable` 参数 |
|
||||
| --table-mapping | array | `[]` | 为表名 -> 模型增加映射关系 比如 ['users:Account'] |
|
||||
| --ignore-tables | array | `[]` | 不需要生成模型的表名 比如 ['users'] |
|
||||
| --with-comments | bool | `false` | 是否增加字段注释 |
|
||||
| --property-case | int | `0` | 字段类型 0 蛇形 1 驼峰 |
|
||||
|
||||
当使用 `--property-case` 将字段类型转化为驼峰时,还需要手动在模型中加入 `Hyperf\Database\Model\Concerns\CamelCase`。
|
||||
|
||||
对应配置也可以配置到 `databases.{pool}.commands.gen:model` 中,如下
|
||||
|
||||
> 中划线都需要转化为下划线
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Hyperf\Database\Commands\ModelOption;
|
||||
|
||||
return [
|
||||
'default' => [
|
||||
// 忽略其他配置
|
||||
'commands' => [
|
||||
'gen:model' => [
|
||||
'path' => 'app/Model',
|
||||
'force_casts' => true,
|
||||
'inheritance' => 'Model',
|
||||
'uses' => '',
|
||||
'refresh_fillable' => true,
|
||||
'table_mapping' => [],
|
||||
'with_comments' => true,
|
||||
'property_case' => ModelOption::PROPERTY_SNAKE_CASE,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
```
|
||||
|
||||
创建的模型如下
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Model;
|
||||
|
||||
use Hyperf\DbConnection\Model\Model;
|
||||
|
||||
/**
|
||||
* @property $id
|
||||
* @property $name
|
||||
* @property $gender
|
||||
* @property $created_at
|
||||
* @property $updated_at
|
||||
*/
|
||||
class User extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'user';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = ['id', 'name', 'gender', 'created_at', 'updated_at'];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = ['id' => 'integer', 'gender' => 'integer'];
|
||||
}
|
||||
```
|
||||
|
||||
## Visitors
|
||||
|
||||
框架提供了几个 `Visitors`,方便用户对脚本能力进行扩展。使用方法很简单,只需要在 `visitors` 配置中,添加对应的 `Visitor` 即可。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
'default' => [
|
||||
// 忽略其他配置
|
||||
'commands' => [
|
||||
'gen:model' => [
|
||||
'visitors' => [
|
||||
Hyperf\Database\Commands\Ast\ModelRewriteKeyInfoVisitor::class
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
```
|
||||
|
||||
### 可选 Visitors
|
||||
|
||||
- Hyperf\Database\Commands\Ast\ModelRewriteKeyInfoVisitor
|
||||
|
||||
此 `Visitor` 可以根据数据库中主键,生成对应的 `$incrementing` `$primaryKey` 和 `$keyType`。
|
||||
|
||||
- Hyperf\Database\Commands\Ast\ModelRewriteSoftDeletesVisitor
|
||||
|
||||
此 `Visitor` 可以根据 `DELETED_AT` 常量判断该模型是否含有软删除字段,如果存在,则添加对应的 Trait `SoftDeletes`。
|
||||
|
||||
- Hyperf\Database\Commands\Ast\ModelRewriteTimestampsVisitor
|
||||
|
||||
此 `Visitor` 可以根据 `created_at` 和 `updated_at` 自动判断,是否启用默认记录 `创建和修改时间` 的功能。
|
@ -146,3 +146,47 @@ User::query(true)->where('gender', '>', 1)->delete();
|
||||
当生产环境使用了模型缓存时,如果已经建立了对应缓存数据,但此时又因为逻辑变更,添加了新的字段,并且默认值不是 `0`、`空字符`、`null` 这类数据时,就会导致在数据查询时,从缓存中查出来的数据与数据库中的数据不一致。
|
||||
|
||||
对于这种情况,我们可以修改 `use_default_value` 为 `true`,并添加 `Hyperf\DbConnection\Listener\InitTableCollectorListener` 到 `listener.php` 配置中,使 Hyperf 应用在启动时主动去获取数据库的字段信息,并在获取缓存数据时与之比较并进行缓存数据修正。
|
||||
|
||||
### EagerLoad
|
||||
|
||||
当我们使用模型关系时,可以通过 `load` 解决 `N+1` 的问题,但仍然需要查一次数据库。模型缓存通过重写了 `ModelBuilder`,可以让用户尽可能的从缓存中拿到对应的模型。
|
||||
|
||||
> 本功能不支持 `morphTo` 和不是只有 `whereIn` 查询的关系模型。
|
||||
|
||||
以下提供两种方式:
|
||||
|
||||
1. 配置 EagerLoadListener,直接使用 `loadCache` 方法。
|
||||
|
||||
修改 `listeners.php` 配置
|
||||
|
||||
```php
|
||||
return [
|
||||
Hyperf\ModelCache\Listener\EagerLoadListener::class,
|
||||
];
|
||||
```
|
||||
|
||||
通过 `loadCache` 方法,加载对应的模型关系。
|
||||
|
||||
```php
|
||||
$books = Book::findManyFromCache([1,2,3]);
|
||||
$books->loadCache(['user']);
|
||||
|
||||
foreach ($books as $book){
|
||||
var_dump($book->user);
|
||||
}
|
||||
```
|
||||
|
||||
2. 使用 EagerLoader
|
||||
|
||||
```php
|
||||
use Hyperf\ModelCache\EagerLoad\EagerLoader;
|
||||
use Hyperf\Utils\ApplicationContext;
|
||||
|
||||
$books = Book::findManyFromCache([1,2,3]);
|
||||
$loader = ApplicationContext::getContainer()->get(EagerLoader::class);
|
||||
$loader->load($books, ['user']);
|
||||
|
||||
foreach ($books as $book){
|
||||
var_dump($book->user);
|
||||
}
|
||||
```
|
||||
|
@ -19,13 +19,13 @@ $ php bin/hyperf.php db:model table_name
|
||||
可选参数如下:
|
||||
|
||||
| 参数 | 类型 | 默认值 | 备注 |
|
||||
|:------------------:|:------:|:-----------------:|:-----------------------------------------------:|
|
||||
| :----------------: | :----: | :-------------------------------: | :-----------------------------------------------: |
|
||||
| --pool | string | `default` | 连接池,脚本会根据当前连接池配置创建 |
|
||||
| --path | string | `app/Model` | 模型路径 |
|
||||
| --force-casts | bool | `false` | 是否强制重置 `casts` 参数 |
|
||||
| --prefix | string | 空字符串 | 表前缀 |
|
||||
| --inheritance | string | `Model` | 父类 |
|
||||
| --uses | string | `App\Model\Model` | 配合 `inheritance` 使用 |
|
||||
| --uses | string | `Hyperf\DbConnection\Model\Model` | 配合 `inheritance` 使用 |
|
||||
| --refresh-fillable | bool | `false` | 是否刷新 `fillable` 参数 |
|
||||
| --table-mapping | array | `[]` | 为表名 -> 模型增加映射关系 比如 ['users:Account'] |
|
||||
| --ignore-tables | array | `[]` | 不需要生成模型的表名 比如 ['users'] |
|
||||
@ -110,7 +110,7 @@ class User extends Model
|
||||
## 模型成员变量
|
||||
|
||||
| 参数 | 类型 | 默认值 | 备注 |
|
||||
|:------------:|:------:|:-------:|:--------------------:|
|
||||
| :----------: | :----: | :-----: | :------------------: |
|
||||
| connection | string | default | 数据库连接 |
|
||||
| table | string | 无 | 数据表名称 |
|
||||
| primaryKey | string | id | 模型主键 |
|
||||
|
@ -217,11 +217,10 @@ $res = Db::table('user')->select('gender', Db::raw('COUNT(0) AS `count`'))->grou
|
||||
|
||||
### 强制索引
|
||||
|
||||
数据库出现的慢查问题, 90% 以上是索引不对, 其中有部分查询是因为数据库服务器的 `查询优化器` 没有使用最佳索引, 这时候就需要使用强制强制索引:
|
||||
数据库出现的慢查问题, 90% 以上是索引不对, 其中有部分查询是因为数据库服务器的 `查询优化器` 没有使用最佳索引, 这时候就需要使用强制索引:
|
||||
|
||||
```php
|
||||
Db::table(Db::raw(sprintf("{$table} FORCE INDEX({$index})");
|
||||
|
||||
Db::table(Db::raw("{$table} FORCE INDEX({$index})"));
|
||||
```
|
||||
|
||||
### 原生方法
|
||||
|
@ -16,6 +16,8 @@ composer require hyperf/guzzle
|
||||
composer require overtrue/flysystem-qiniu
|
||||
# 使用内存适配器时执行
|
||||
composer require league/flysystem-memory
|
||||
# 使用腾讯云 COS 适配器时执行
|
||||
composer require overtrue/flysystem-cos
|
||||
```
|
||||
|
||||
安装完成后,执行
|
||||
@ -128,7 +130,7 @@ return [
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. S3 存储请确认安装 `hyperf/guzzle` 组件以提供协程化支持。阿里云、七牛云存储请[开启 Curl Hook](/zh-cn/coroutine?id=swoole-runtime-hook-level)来使用协程。因 Curl Hook 的参数支持性问题,请使用 Swoole 4.4.13 以上版本。
|
||||
1. S3 存储请确认安装 `hyperf/guzzle` 组件以提供协程化支持。阿里云、七牛云、腾讯云云存储请[开启 Curl Hook](/zh-cn/coroutine?id=swoole-runtime-hook-level)来使用协程。因 Curl Hook 的参数支持性问题,请使用 Swoole 4.4.13 以上版本。
|
||||
2. minIO, ceph radosgw 等私有对象存储方案均支持 S3 协议,可以使用 S3 适配器。
|
||||
3. 使用 Local 驱动时,根目录是配置好的地址,而不是操作系统的根目录。例如,Local 驱动 `root` 设置为 `/var/www`, 则本地磁盘上的 `/var/www/public/file.txt` 通过 flysystem API 访问时应使用 `/public/file.txt` 或 `public/file.txt` 。
|
||||
4. 以阿里云 OSS 为例,1 核 1 进程读操作性能对比:
|
||||
@ -241,6 +243,21 @@ return [
|
||||
'bucket' => env('QINIU_BUCKET'),
|
||||
'domain' => env('QINIU_DOMAIN'),
|
||||
],
|
||||
'cos' => [
|
||||
'driver' => \Hyperf\Filesystem\Adapter\CosAdapterFactory::class,
|
||||
'region' => env('COS_REGION'),
|
||||
'credentials' => [
|
||||
'appId' => env('COS_APPID'),
|
||||
'secretId' => env('COS_SECRET_ID'),
|
||||
'secretKey' => env('COS_SECRET_KEY'),
|
||||
],
|
||||
'bucket' => env('COS_BUCKET'),
|
||||
'read_from_cdn' => false,
|
||||
// 'timeout' => 60,
|
||||
// 'connect_timeout' => 60,
|
||||
// 'cdn' => '',
|
||||
// 'scheme' => 'https',
|
||||
],
|
||||
],
|
||||
];
|
||||
```
|
||||
|
@ -38,7 +38,7 @@ message HiReply {
|
||||
- 使用 protoc 生成示例代码
|
||||
|
||||
```
|
||||
# 使用 linux 包管理工具安装 protoc, 下面以 alpine 为例, 也可以参考 hyper-skeleton 下的 Dockerfile
|
||||
# 使用 linux 包管理工具安装 protoc, 下面以 alpine 为例, 也可以参考 hyperf-skeleton 下的 Dockerfile
|
||||
apk add protobuf
|
||||
|
||||
# 使用 protoc 自动生成代码
|
||||
@ -157,7 +157,7 @@ class HiClient extends BaseClient
|
||||
{
|
||||
public function sayHello(HiUser $argument)
|
||||
{
|
||||
return $this->simpleRequest(
|
||||
return $this->_simpleRequest(
|
||||
'/grpc.hi/sayHello',
|
||||
$argument,
|
||||
[HiReply::class, 'decode']
|
||||
|
@ -122,3 +122,67 @@ $client = make(Client::class, [
|
||||
],
|
||||
]);
|
||||
```
|
||||
|
||||
## 使用 `ClassMap` 替换 `GuzzleHttp\Client`
|
||||
|
||||
如果第三方组件并没有提供可以替换 `Handler` 的接口,我们也可以通过 `ClassMap` 功能,直接替换 `Client` 来达到将客户端协程化的目的。
|
||||
|
||||
> 当然,也可以使用 SWOOLE_HOOK 达到相同的目的。
|
||||
|
||||
代码示例如下:
|
||||
|
||||
class_map/GuzzleHttp/Client.php
|
||||
|
||||
```php
|
||||
<?php
|
||||
namespace GuzzleHttp;
|
||||
|
||||
use GuzzleHttp\Psr7;
|
||||
use Hyperf\Guzzle\CoroutineHandler;
|
||||
use Hyperf\Utils\Coroutine;
|
||||
|
||||
class Client implements ClientInterface
|
||||
{
|
||||
// 代码省略其他不变的代码
|
||||
|
||||
public function __construct(array $config = [])
|
||||
{
|
||||
$inCoroutine = Coroutine::inCoroutine();
|
||||
if (!isset($config['handler'])) {
|
||||
// 对应的 Handler 可以按需选择 CoroutineHandler 或 PoolHandler
|
||||
$config['handler'] = HandlerStack::create($inCoroutine ? new CoroutineHandler() : null);
|
||||
} elseif ($inCoroutine && $config['handler'] instanceof HandlerStack) {
|
||||
$config['handler']->setHandler(new CoroutineHandler());
|
||||
} elseif (!is_callable($config['handler'])) {
|
||||
throw new \InvalidArgumentException('handler must be a callable');
|
||||
}
|
||||
|
||||
// Convert the base_uri to a UriInterface
|
||||
if (isset($config['base_uri'])) {
|
||||
$config['base_uri'] = Psr7\uri_for($config['base_uri']);
|
||||
}
|
||||
|
||||
$this->configureDefaults($config);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
config/autoload/annotations.php
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
return [
|
||||
'scan' => [
|
||||
// ...
|
||||
'class_map' => [
|
||||
Client::class => BASE_PATH . '/class_map/GuzzleHttp/Client.php',
|
||||
],
|
||||
],
|
||||
];
|
||||
```
|
||||
|
@ -405,6 +405,6 @@ Router::get('/metrics', function(){
|
||||
|
||||
> 本节只适用于 Prometheus 驱动
|
||||
|
||||
如果您启用了默认指标,`Hyperf/Metric` 为您准备了一个开箱即用的 Grafana 控制台。下载控制台 [json 文件](https://raw.githubusercontent.com/hyperf/hyperf/master/src/metric/grafana.json),导入 Grafana 中即可使用。
|
||||
如果您启用了默认指标,`Hyperf/Metric` 为您准备了一个开箱即用的 Grafana 控制台。下载控制台 [json 文件](https://cdn.jsdelivr.net/gh/hyperf/hyperf/src/metric/grafana.json),导入 Grafana 中即可使用。
|
||||
|
||||
![grafana](imgs/grafana.png)
|
||||
|
130
docs/zh-cn/nacos.md
Normal file
130
docs/zh-cn/nacos.md
Normal file
@ -0,0 +1,130 @@
|
||||
# Nacos
|
||||
|
||||
一个 `Nacos` 的 `PHP` 协程客户端,与 `Hyperf` 的配置中心、微服务治理完美结合。
|
||||
|
||||
## 安装
|
||||
|
||||
```shell
|
||||
composer require hyperf/nacos
|
||||
```
|
||||
|
||||
### 发布配置文件
|
||||
|
||||
```shell
|
||||
php bin/hyperf.php vendor:publish hyperf/nacos
|
||||
```
|
||||
|
||||
### 目录结构
|
||||
|
||||
```
|
||||
./src
|
||||
├── Api
|
||||
│ ├── AbstractNacos.php
|
||||
│ ├── NacosConfig.php
|
||||
│ ├── NacosInstance.php
|
||||
│ ├── NacosOperator.php
|
||||
│ └── NacosService.php
|
||||
├── Client.php
|
||||
├── Config
|
||||
│ ├── FetchConfigProcess.php
|
||||
│ ├── OnPipeMessageListener.php
|
||||
│ └── PipeMessage.php
|
||||
├── ConfigProvider.php
|
||||
├── Contract
|
||||
│ └── LoggerInterface.php
|
||||
├── Exception
|
||||
│ ├── InvalidArgumentException.php
|
||||
│ ├── NacosThrowable.php
|
||||
│ └── RuntimeException.php
|
||||
├── Instance.php
|
||||
├── Listener
|
||||
│ ├── MainWorkerStartListener.php
|
||||
│ └── OnShutdownListener.php
|
||||
├── Model
|
||||
│ ├── AbstractModel.php
|
||||
│ ├── ConfigModel.php
|
||||
│ ├── InstanceModel.php
|
||||
│ └── ServiceModel.php
|
||||
├── Process
|
||||
│ └── InstanceBeatProcess.php
|
||||
└── Service.php
|
||||
```
|
||||
|
||||
## 服务与实例
|
||||
|
||||
`MainWorkerStartListener.php` 将在系统启动完成时自动完成 `实例注册`,`服务注册`
|
||||
|
||||
如果需要在服务下线时自动注销服务,请增加如下配置,以监听 `Shutdown` 事件
|
||||
|
||||
```php
|
||||
// config/autoload/server.php
|
||||
|
||||
return [
|
||||
// ...other
|
||||
'callbacks' => [
|
||||
// ...other
|
||||
SwooleEvent::ON_SHUTDOWN => [Hyperf\Framework\Bootstrap\ShutdownCallback::class, 'onShutdown']
|
||||
]
|
||||
];
|
||||
```
|
||||
|
||||
### 获取当前实例
|
||||
|
||||
```php
|
||||
$instance = new \Hyperf\Nacos\Instance();
|
||||
```
|
||||
|
||||
### 获取当前服务
|
||||
|
||||
```php
|
||||
$service = new \Hyperf\Nacos\Service();
|
||||
```
|
||||
|
||||
### 获取一个服务的最优节点
|
||||
|
||||
```php
|
||||
$instance = make(NacosInstance::class);
|
||||
|
||||
$service = new ServiceModel([
|
||||
'service_name' => 'hyperf',
|
||||
'group_name' => 'api',
|
||||
'namespace_id' => '5ce9d1c1-6732-4ccc-ae1f-5139af86a845'
|
||||
]);
|
||||
|
||||
$optimal = $instance->getOptimal($service);
|
||||
|
||||
```
|
||||
|
||||
## 配置中心
|
||||
|
||||
`MainWorkerStartListener.php` 系统启动时将拉取远程配置, 并合入`hyperf` 的 `Config`
|
||||
|
||||
`FetchConfigProcess.php` 自定义进程将监听配置, 若有更新将发送 `PipeMessage` 到各服务`worker` 进程, 并合入当前进程的 `Config`
|
||||
|
||||
如果服务如下配置
|
||||
```php
|
||||
// config/autoload/nacos.php
|
||||
|
||||
return [
|
||||
// ...other
|
||||
'config_reload_interval' => 3,
|
||||
// 远程配置合并节点, 默认 config 根节点
|
||||
'config_append_node' => 'nacos_config',
|
||||
'listener_config' => [
|
||||
// 配置项 dataId, group, tenant, type, content
|
||||
[
|
||||
'data_id' => 'hyperf-service-config',
|
||||
'group' => 'DEFAULT_GROUP',
|
||||
],
|
||||
[
|
||||
'data_id' => 'hyperf-service-config-yml',
|
||||
'group' => 'DEFAULT_GROUP',
|
||||
'type' => 'yml',
|
||||
],
|
||||
],
|
||||
];
|
||||
```
|
||||
|
||||
系统将自动监听`listener_config` 中的配置,并将其合并入`hyperf Config` 对象的指定(`config_append_node`) 节点,可以用`config('nacos_config.***')` 获取,若没有配置 `config_append_node` 项,将会并入 `Config` 对象根节点。
|
||||
|
||||
> 所有配置的 `键(key)` 在实际发起 API 请求时会自动从下划线风格转换为驼峰风格。
|
@ -8,4 +8,21 @@
|
||||
|
||||
## 通过容器获取的类都是单例
|
||||
|
||||
通过依赖注入容器获取的都是进程内持久化的,是多个协程共享的,所以不能包含任何的请求唯一的数据或协程唯一的数据,这类型的数据都通过协程上下文去处理,具体请仔细阅读 [依赖注入](./zh-cn/di.md) 和 [协程](./zh-cn/coroutine.md) 章节。
|
||||
通过依赖注入容器获取的都是进程内持久化的,是多个协程共享的,所以不能包含任何的请求唯一的数据或协程唯一的数据,这类型的数据都通过协程上下文去处理,具体请仔细阅读 [依赖注入](zh-cn/di.md) 和 [协程](zh-cn/coroutine.md) 章节。
|
||||
|
||||
## 项目部署
|
||||
|
||||
> 官方的 Dockerfile 已经完成了以下操作。
|
||||
|
||||
线上代码部署时,请务必开启 `scan_cacheable`。
|
||||
|
||||
开启此配置后,首次扫描时会生成代理类和注解缓存,再次启动时,则可以直接使用缓存,极大优化内存使用率和启动速度。因为跳过了扫描阶段,所以会依赖 `Composer Class Map`,故我们必须要执行 `--optimize-autoloader` 优化索引。
|
||||
|
||||
综上,线上更新代码,重启项目前,需要执行以下命令
|
||||
|
||||
```bash
|
||||
# 优化 Composer 索引
|
||||
composer dump-autoload -o
|
||||
# 生成代理类和注解缓存
|
||||
php bin/hyperf.php
|
||||
```
|
||||
|
@ -35,7 +35,7 @@ composer create-project hyperf/hyperf-skeleton
|
||||
|
||||
```
|
||||
# 下载并运行 hyperf/hyperf 镜像,并将镜像内的项目目录绑定到宿主机的 /tmp/skeleton 目录
|
||||
docker run -v /tmp/skeleton:/hyperf-skeleton -p 9501:9501 -it --entrypoint /bin/sh hyperf/hyperf:7.2-alpine-cli
|
||||
docker run -v /tmp/skeleton:/hyperf-skeleton -p 9501:9501 -it --entrypoint /bin/sh hyperf/hyperf:latest
|
||||
|
||||
# 镜像容器运行后,在容器内安装 Composer
|
||||
wget https://github.com/composer/composer/releases/download/1.8.6/composer.phar
|
||||
|
@ -230,7 +230,7 @@ class IndexController
|
||||
> Tips: 您也可以将启动 Server 的命令配置在 IDE 上,便可直接通过 IDE 的 `启动/停止` 操作快捷的完成 `启动服务` 或 `重启服务` 的操作。
|
||||
> 且非视图开发时可以采用 [TDD(Test-Driven Development)](https://baike.baidu.com/item/TDD/9064369) 测试驱动开发来进行开发,这样不仅可以省略掉服务重启和频繁切换窗口的麻烦,还可保证接口数据的正确性。
|
||||
|
||||
> 另外,在文档 [协程组件库](./zh-cn/awesome-components?id=%e7%83%ad%e6%9b%b4%e6%96%b0%e7%83%ad%e9%87%8d%e8%bd%bd) 一章中提供了多种由社区开发者支持的 热更新/热重载 的解决方案,如仍希望采用 热更新/热重载 方案可再深入了解。
|
||||
> 另外,在文档 [协程组件库](zh-cn/awesome-components?id=%e7%83%ad%e6%9b%b4%e6%96%b0%e7%83%ad%e9%87%8d%e8%bd%bd) 一章中提供了多种由社区开发者支持的 热更新/热重载 的解决方案,如仍希望采用 热更新/热重载 方案可再深入了解。
|
||||
|
||||
## 多端口监听
|
||||
|
||||
|
@ -1,5 +1,82 @@
|
||||
# 常见问题
|
||||
|
||||
## `Inject` 或 `Value` 注解不生效
|
||||
|
||||
`2.0` 使用了构造函数中注入 `Inject` 和 `Value` 的功能,以下两种场景,可能会导致注入失效,请注意使用。
|
||||
|
||||
1. 原类没有使用 `Inject` 或 `Value`,但父类使用了 `Inject` 或 `Value`,且原类写了构造函数,同时又没有调用父类构造函数的情况。
|
||||
|
||||
这样就会导致原类不会生成代理类,而实例化的时候又调用了自身的构造函数,故没办法执行到父类的构造函数。
|
||||
所以父类代理类中的方法 `__handlePropertyHandler` 就不会执行,那么 `Inject` 或 `Value` 注解就不会生效。
|
||||
|
||||
```php
|
||||
class ParentClass {
|
||||
/**
|
||||
* @Inject
|
||||
* @var Service
|
||||
*/
|
||||
protected $value;
|
||||
}
|
||||
|
||||
class Origin extends ParentClass
|
||||
{
|
||||
public function __construct() {}
|
||||
}
|
||||
```
|
||||
|
||||
2. 原类没有使用 `Inject` 或 `Value`,但 `Trait` 中使用了 `Inject` 或 `Value`。
|
||||
|
||||
这样就会导致原类不会生成代理类,故没办法执行构造函数里的 `__handlePropertyHandler`,所以 `Trait` 的 `Inject` 或 `Value` 注解就不会生效。
|
||||
|
||||
```php
|
||||
trait OriginTrait {
|
||||
/**
|
||||
* @Inject
|
||||
* @var Service
|
||||
*/
|
||||
protected $value;
|
||||
}
|
||||
|
||||
class Origin
|
||||
{
|
||||
use OriginTrait;
|
||||
}
|
||||
```
|
||||
|
||||
基于上述两种情况,可见 `原类` 是否生成代理类至关重要,所以,如果使用了带有 `Inject` 或 `Value` 的 `Trait` 和 `父类` 时,给原类添加一个 `Inject`,即可解决上述两种情况。
|
||||
|
||||
```php
|
||||
|
||||
use Hyperf\Contract\StdoutLoggerInterface;
|
||||
|
||||
trait OriginTrait {
|
||||
/**
|
||||
* @Inject
|
||||
* @var Service
|
||||
*/
|
||||
protected $trait;
|
||||
}
|
||||
|
||||
class ParentClass {
|
||||
/**
|
||||
* @Inject
|
||||
* @var Service
|
||||
*/
|
||||
protected $value;
|
||||
}
|
||||
|
||||
class Origin extends ParentClass
|
||||
{
|
||||
use OriginTrait;
|
||||
|
||||
/**
|
||||
* @Inject
|
||||
* @var StdoutLoggerInterface
|
||||
*/
|
||||
protected $logger;
|
||||
}
|
||||
```
|
||||
|
||||
## Swoole 短名未关闭
|
||||
|
||||
```
|
||||
@ -8,18 +85,6 @@
|
||||
|
||||
您需要在您的 php.ini 配置文件增加 `swoole.use_shortname = 'Off'` 配置项
|
||||
|
||||
如果您使用的是 1.0.x 版本,这也可能是因为你按以下的方式设置了
|
||||
|
||||
```
|
||||
// 在 1.0 系列版本下
|
||||
// 这些都是错误的,注意 `大小写` 和 `引号`
|
||||
swoole.use_shortname = 'off'
|
||||
swoole.use_shortname = off
|
||||
swoole.use_shortname = Off
|
||||
// 下面的才是正确的
|
||||
swoole.use_shortname = 'Off'
|
||||
```
|
||||
|
||||
> 注意该配置必须于 php.ini 内配置,无法通过 ini_set() 函数来重写
|
||||
|
||||
当然,也可以通过以下的命令来启动服务,在执行 PHP 命令时关闭掉 Swoole 短名功能
|
||||
@ -28,40 +93,6 @@ swoole.use_shortname = 'Off'
|
||||
php -d swoole.use_shortname=Off bin/hyperf.php start
|
||||
```
|
||||
|
||||
## 代理类缓存
|
||||
|
||||
代理类缓存一旦生成,将不会再重新覆盖。所以当你修改了已经生成代理类的文件时,需要手动清理。
|
||||
|
||||
代理类位置如下
|
||||
|
||||
```
|
||||
runtime/container/proxy/
|
||||
```
|
||||
|
||||
重新生成缓存命令,新缓存会覆盖原目录
|
||||
|
||||
```bash
|
||||
vendor/bin/init-proxy.sh
|
||||
```
|
||||
|
||||
删除代理类缓存
|
||||
|
||||
```bash
|
||||
rm -rf ./runtime/container/proxy
|
||||
```
|
||||
|
||||
所以单测命令可以使用以下代替:
|
||||
|
||||
```bash
|
||||
vendor/bin/init-proxy.sh && composer test
|
||||
```
|
||||
|
||||
同理,启动命令可以使用以下代替
|
||||
|
||||
```bash
|
||||
vendor/bin/init-proxy.sh && php bin/hyperf.php start
|
||||
```
|
||||
|
||||
## 异步队列消息丢失
|
||||
|
||||
如果在使用 `async-queue` 组件时,发现 `handle` 中的方法没有执行,请先检查以下几种情况:
|
||||
@ -74,29 +105,26 @@ vendor/bin/init-proxy.sh && php bin/hyperf.php start
|
||||
1. killall php
|
||||
2. 修改 `async-queue` 配置 `channel`
|
||||
|
||||
## 1.1.24 - 1.1.26 版本 SymfonyEventDispatcher 报错
|
||||
|
||||
因为 `symfony/console` 默认使用的 `^4.2` 版本,而 `symfony/event-dispatcher` 的 `^4.3` 版本与 `<4.3` 版本不兼容。
|
||||
|
||||
`hyperf/framework` 默认推荐使用 `^4.3` 版本的 `symfony/event-dispatcher`,就有一定概率导致实现上的冲突。
|
||||
|
||||
如果有类似的情况出现,可以尝试以下操作
|
||||
|
||||
```
|
||||
rm -rf vendor
|
||||
rm -rf composer.lock
|
||||
composer require "symfony/event-dispatcher:^4.3"
|
||||
```
|
||||
|
||||
1.1.27 版本中,会在 `composer.json` 中添加以下配置,来处理这个问题。
|
||||
|
||||
```
|
||||
"conflict": {
|
||||
"symfony/event-dispatcher": "<4.3"
|
||||
},
|
||||
```
|
||||
|
||||
## 使用 AMQP 组件报 `Swoole\Error: API must be called in the coroutine` 错误
|
||||
|
||||
可以在 `config/autoload/amqp.php` 配置文件中将 `close_on_destruct` 改为 `false` 即可。
|
||||
|
||||
## 使用 Swoole 4.5 版本和 view 组件时访问接口出现 404
|
||||
|
||||
使用 Swoole 4.5 版本和 view 组件如果出现接口 404 的问题,可以尝试删除 `config/autoload/server.php` 文件中的 `static_handler_locations` 配置项。
|
||||
|
||||
此配置下的路径都会被认为是静态文件路由,所以如果配置了`/`,就会导致所有接口都会被认为是文件路径,导致接口 404。
|
||||
|
||||
## 代码不生效
|
||||
|
||||
当碰到修改后的代码不生效的问题,请执行以下命令
|
||||
|
||||
```bash
|
||||
composer dump-autoload -o
|
||||
```
|
||||
|
||||
开发阶段,请不要设置 `scan_cacheable` 为 `true`,它会导致 `收集器缓存` 存在时,不会再次扫描文件。另外,官方骨架包中的 `Dockerfile` 是默认开启这个配置的,`Docker` 环境下开发的同学,请注意这里。
|
||||
|
||||
> 当环境变量存在 SCAN_CACHEABLE 时,.env 中无法修改这个配置。
|
||||
|
||||
`2.0.0` 和 `2.0.1` 两个版本,判断文件是否修改时,没有判断修改时间相等的情况,所以文件修改后,立马生成缓存的情况(比如使用 `watcher` 组件时), 会导致代码无法及时生效。
|
||||
|
@ -37,7 +37,7 @@ ReactiveX 是 Reactive Extensions 的缩写,一般简写为 Rx,最初是 LIN
|
||||
## 安装
|
||||
|
||||
```bash
|
||||
composer require hyper/reactive-x
|
||||
composer require hyperf/reactive-x
|
||||
```
|
||||
|
||||
## 封装
|
||||
|
@ -15,5 +15,5 @@
|
||||
|
||||
## 版本迭代周期
|
||||
|
||||
Hyperf 采用敏捷开发模式,每周一个迭代计划,并于 `每周的星期四 (UTC/GMT+08:00)` 发布一个版本,通常来说是一个 z 版本的发布,也有可能是一个 y 版本。而对于 x 版本,则会根据实际的研究成果情况而决定具体的迭代计划和时间。
|
||||
Hyperf 采用敏捷开发模式,每周一个迭代计划,并于 `每周的星期一 (UTC/GMT+08:00)` 发布一个版本,通常来说是一个 z 版本的发布,也有可能是一个 y 版本。而对于 x 版本,则会根据实际的研究成果情况而决定具体的迭代计划和时间。
|
||||
关于 Hyperf 采用的版本规则,请查阅 [版本说明](zh-cn/versions.md) 一章。
|
||||
|
@ -208,4 +208,4 @@ public function index(RequestInterface $request)
|
||||
## 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)
|
||||
当您需要对 `路由找不到(404)`、`请求方法不允许(405)` 等 HTTP 异常情况的响应进行自定义处理时,您可直接根据 `HttpExceptionHandler` 的代码实现您自己的异常处理器,并配置您自己的异常处理器。关于异常处理器的逻辑和使用说明,可具体查阅 [异常处理](zh-cn/exception-handler.md)
|
||||
|
@ -70,10 +70,14 @@ use Symfony\Component\HttpFoundation\Request;
|
||||
$get = $this->request->getQueryParams();
|
||||
$post = $this->request->getParsedBody();
|
||||
$cookie = $this->request->getCookieParams();
|
||||
$files = $this->request->getUploadedFiles();
|
||||
$uploadFiles = $this->request->getUploadedFiles() ?? [];
|
||||
$server = $this->request->getServerParams();
|
||||
$xml = $this->request->getBody()->getContents();
|
||||
|
||||
$files = [];
|
||||
/** @var \Hyperf\HttpMessage\Upload\UploadedFile $v */
|
||||
foreach ($uploadFiles as $k => $v) {
|
||||
$files[$k] = $v->toArray();
|
||||
}
|
||||
$app['request'] = new Request($get, $post, [], $cookie, $files, $server, $xml);
|
||||
|
||||
// Do something...
|
||||
@ -90,7 +94,7 @@ $app['request'] = new Request($get,$post,[],$cookie,$files,$server,$xml);
|
||||
```php
|
||||
$response = $app->server->serve();
|
||||
|
||||
return $response->getBody()->getContents();
|
||||
return $response->getContent();
|
||||
```
|
||||
|
||||
## 如何替换缓存
|
||||
|
@ -10,7 +10,7 @@ composer require hyperf/service-governance
|
||||
|
||||
# 注册服务
|
||||
|
||||
注册服务可通过 `@RpcService` 注解对一个类进行定义,即为发布这个服务了,目前 Hyperf 仅适配了 JSON RPC 协议,具体内容也可到 [JSON RPC 服务](./zh-cn/json-rpc.md) 章节了解详情。
|
||||
注册服务可通过 `@RpcService` 注解对一个类进行定义,即为发布这个服务了,目前 Hyperf 仅适配了 JSON RPC 协议,具体内容也可到 [JSON RPC 服务](zh-cn/json-rpc.md) 章节了解详情。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
@ -8,6 +8,14 @@
|
||||
composer require hyperf/signal
|
||||
```
|
||||
|
||||
## 发布配置
|
||||
|
||||
您可以通过下面的命令来发布默认的配置文件到您的项目中:
|
||||
|
||||
```bash
|
||||
php bin/hyperf.php vendor:publish hyperf/signal
|
||||
```
|
||||
|
||||
## 添加处理器
|
||||
|
||||
以下我们监听 `Worker` 进程的 `SIGTERM` 信号,当收到信号后,打印出信号值。
|
||||
@ -42,7 +50,7 @@ class TermSignalHandler implements SignalHandlerInterface
|
||||
|
||||
```
|
||||
|
||||
因为 Worker 进程 SIGTERM 信号被捕获后,无法正常退出,所以用户可以直接 Ctrl+C 退出,或者修改 signal.php 配置
|
||||
因为 Worker 进程接收的 SIGTERM 信号被捕获后,无法正常退出,所以用户可以直接 `Ctrl + C` 退出,或者修改 `config/autoload/signal.php` 配置,如下:
|
||||
|
||||
```php
|
||||
<?php
|
||||
@ -55,7 +63,6 @@ return [
|
||||
],
|
||||
'timeout' => 5.0,
|
||||
];
|
||||
|
||||
```
|
||||
|
||||
`WorkerStopHandler` 触发后,会在 `max_wait_time` 时间后,关掉当前进程。
|
||||
`WorkerStopHandler` 触发后,会在所设置的 [max_wait_time](https://wiki.swoole.com/#/server/setting?id=max_wait_time) 配置时间后,关闭掉当前进程。
|
||||
|
@ -138,3 +138,17 @@ $userId = 20190620;
|
||||
$id = $generator->generate($userId);
|
||||
|
||||
```
|
||||
|
||||
## 在数据库模型中应用
|
||||
|
||||
配置好 Snowflake 以后,我们可以让数据库模型直接使用雪花 id 作为主键。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
class User extends \Hyperf\Database\Model\Model {
|
||||
use \Hyperf\Snowflake\Concern\Snowflake;
|
||||
}
|
||||
```
|
||||
|
||||
上述 User 模型在创建时便会默认使用 Snowflake 算法生成主键。
|
||||
|
@ -52,6 +52,7 @@
|
||||
* [快速开始](zh-cn/db/quick-start.md)
|
||||
* [查询构造器](zh-cn/db/querybuilder.md)
|
||||
* [模型](zh-cn/db/model.md)
|
||||
* [创建脚本](zh-cn/db/gen.md)
|
||||
* [模型关系](zh-cn/db/relationship.md)
|
||||
* [查询分页](zh-cn/db/paginator.md)
|
||||
* [模型事件](zh-cn/db/event.md)
|
||||
@ -72,6 +73,7 @@
|
||||
* [调用链追踪](zh-cn/tracer.md)
|
||||
* [服务监控](zh-cn/metric.md)
|
||||
* [服务重试](zh-cn/retry.md)
|
||||
* [Nacos](zh-cn/nacos.md)
|
||||
|
||||
* 消息队列
|
||||
|
||||
@ -89,6 +91,7 @@
|
||||
* [Consul 协程客户端](zh-cn/consul.md)
|
||||
* [ETCD 协程客户端](zh-cn/etcd.md)
|
||||
* [WebSocket 服务](zh-cn/websocket-server.md)
|
||||
* [TCP 服务](zh-cn/tcp-server.md)
|
||||
* [WebSocket 协程客户端](zh-cn/websocket-client.md)
|
||||
* [Socket.io 服务](zh-cn/socketio-server.md)
|
||||
* [自定义进程](zh-cn/process.md)
|
||||
@ -103,6 +106,7 @@
|
||||
* [重试](zh-cn/retry.md)
|
||||
* [信号处理器](zh-cn/signal.md)
|
||||
* [ReactiveX](zh-cn/reactive-x.md)
|
||||
* [Watcher](zh-cn/watcher.md)
|
||||
|
||||
* 应用部署
|
||||
|
||||
|
78
docs/zh-cn/tcp-server.md
Normal file
78
docs/zh-cn/tcp-server.md
Normal file
@ -0,0 +1,78 @@
|
||||
# TCP 服务
|
||||
|
||||
框架默认提供创建 `TCP/UDP` 服务的能力。只需要进行简易的配置,便可使用。
|
||||
|
||||
## 使用 TCP 服务
|
||||
|
||||
> UDP 服务请自行修改配置
|
||||
|
||||
### 创建 TcpServer 类
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Hyperf\Contract\OnReceiveInterface;
|
||||
|
||||
class TcpServer implements OnReceiveInterface
|
||||
{
|
||||
public function onReceive($server, int $fd, int $fromId, string $data): void
|
||||
{
|
||||
$server->send($fd, 'recv:' . $data);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### 创建对应配置
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Hyperf\Server\Server;
|
||||
use Hyperf\Server\SwooleEvent;
|
||||
|
||||
return [
|
||||
// 删除其他不相关的配置项
|
||||
'servers' => [
|
||||
[
|
||||
'name' => 'tcp',
|
||||
'type' => Server::SERVER_BASE,
|
||||
'host' => '0.0.0.0',
|
||||
'port' => 9504,
|
||||
'sock_type' => SWOOLE_SOCK_TCP,
|
||||
'callbacks' => [
|
||||
SwooleEvent::ON_RECEIVE => [App\Controller\TcpServer::class, 'onReceive'],
|
||||
],
|
||||
'settings' => [
|
||||
// 按需配置
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
```
|
||||
|
||||
### 实现客户端
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
$client = new \Swoole\Client(SWOOLE_SOCK_TCP);
|
||||
$client->connect('127.0.0.1', 9504);
|
||||
$client->send('Hello World.');
|
||||
$ret = $client->recv(); // recv:Hello World.
|
||||
```
|
||||
|
||||
## 事件
|
||||
|
||||
| 事件 | 备注 |
|
||||
| :---------------------: | :--------------: |
|
||||
| SwooleEvent::ON_CONNECT | 监听连接进入事件 |
|
||||
| SwooleEvent::ON_RECEIVE | 监听数据接收事件 |
|
||||
| SwooleEvent::ON_CLOSE | 监听连接关闭事件 |
|
@ -217,7 +217,7 @@ return [
|
||||
'arguments' => 'arguments',
|
||||
'result' => 'result',
|
||||
],
|
||||
// 数据库客户端 (hyper/database)
|
||||
// 数据库客户端 (hyperf/database)
|
||||
'db' => [
|
||||
'db.query' => 'db.query',
|
||||
'db.statement' => 'db.statement',
|
||||
|
@ -245,6 +245,12 @@ return [
|
||||
];
|
||||
```
|
||||
|
||||
## 启动服务并测试访问接口
|
||||
|
||||
使用 Swoole 4.5 版本和 view 组件如果出现接口 404 的问题,可以尝试删除 `config/autoload/server.php` 文件中的 `static_handler_locations` 配置项。
|
||||
|
||||
此配置下的路径都会被认为是静态文件路由,所以如果配置了`/`,就会导致所有接口都会被认为是文件路径,导致接口 404。
|
||||
|
||||
## 完成升级
|
||||
|
||||
至此,2.0 版本升级即已完成,但由于 Hyperf 的各个底层文件都是可以通过 DI 来实现重写的,如您重写了某些本次升级调整到了的框架内部文件,您仍需再根据您的实际情况进行一定的调整。
|
||||
|
72
docs/zh-cn/watcher.md
Normal file
72
docs/zh-cn/watcher.md
Normal file
@ -0,0 +1,72 @@
|
||||
# 热更新 Watcher
|
||||
|
||||
自从 `2.0` 版本使用了 `BetterReflection` 来收集扫描目录内的 `语法树` 和 `反射数据`,导致扫描速度相较 `1.1` 慢了不少。
|
||||
|
||||
> 首次启动,因为没有任何缓存,所以会比较慢,当二次启动时,会按照文件修改时间,进行动态收集,但因为仍需要实例化 `BetterReflection`,所以启动时间仍然比较长。
|
||||
|
||||
`Watcher` 组件除了解决上述启动问题,还提供了文件修改后立马重启的功能。
|
||||
|
||||
## 安装
|
||||
|
||||
```
|
||||
composer require hyperf/watcher --dev
|
||||
```
|
||||
|
||||
## 配置
|
||||
|
||||
### 发布配置
|
||||
|
||||
```bash
|
||||
php bin/hyperf.php vendor:publish hyperf/watcher
|
||||
```
|
||||
|
||||
### 配置说明
|
||||
|
||||
| 配置 | 默认值 | 备注 |
|
||||
| :------------: | :--------------: | :-------------------------------------------------------: |
|
||||
| driver | `ScanFileDriver` | 默认定时扫描文件驱动 |
|
||||
| bin | `php` | 用于启动服务的脚本 例如 `php -d swoole.use_shortname=Off` |
|
||||
| watch.dir | `app`, `config` | 监听目录 |
|
||||
| watch.file | `.env` | 监听文件 |
|
||||
| watch.interval | `2000` | 扫描间隔(毫秒) |
|
||||
|
||||
## 支持驱动
|
||||
|
||||
| 驱动 | 备注 |
|
||||
| :----------------------------------: | :---------------------------------: |
|
||||
| Hyperf\Watcher\Driver\ScanFileDriver | 无需扩展 |
|
||||
| Hyperf\Watcher\Driver\FswatchDriver | 需要安装 fswatch |
|
||||
| Hyperf\Watcher\Driver\FindDriver | 需要安装 find,MAC 下需要安装 gfind |
|
||||
|
||||
### `fswatch` 安装
|
||||
|
||||
Mac
|
||||
|
||||
```bash
|
||||
brew install fswatch
|
||||
```
|
||||
|
||||
其他
|
||||
|
||||
```bash
|
||||
wget https://github.com/emcrisostomo/fswatch/releases/download/1.14.0/fswatch-1.14.0.tar.gz \
|
||||
&& tar -xf fswatch-1.14.0.tar.gz \
|
||||
&& cd fswatch-1.14.0/ \
|
||||
&& ./configure \
|
||||
&& make \
|
||||
&& make install
|
||||
```
|
||||
|
||||
## 启动
|
||||
|
||||
因为目录的关系,需要在项目根目录中运行。
|
||||
|
||||
```bash
|
||||
php bin/hyperf.php server:watch
|
||||
```
|
||||
|
||||
## 不足
|
||||
- 暂时 Alpine Docker 环境下,稍微有点问题,后续会完善。
|
||||
- 删除文件需要手动重启才能生效。
|
||||
- vendor 中的文件需要使用 classmap 形式自动加载才能被扫描。(即执行`composer dump-autoload -o`)
|
||||
|
@ -63,24 +63,24 @@ use Swoole\WebSocket\Server as WebSocketServer;
|
||||
|
||||
class WebSocketController implements OnMessageInterface, OnOpenInterface, OnCloseInterface
|
||||
{
|
||||
public function onMessage(WebSocketServer $server, Frame $frame): void
|
||||
public function onMessage($server, Frame $frame): void
|
||||
{
|
||||
$server->push($frame->fd, 'Recv: ' . $frame->data);
|
||||
}
|
||||
|
||||
public function onClose(Server $server, int $fd, int $reactorId): void
|
||||
public function onClose($server, int $fd, int $reactorId): void
|
||||
{
|
||||
var_dump('closed');
|
||||
}
|
||||
|
||||
public function onOpen(WebSocketServer $server, Request $request): void
|
||||
public function onOpen($server, Request $request): void
|
||||
{
|
||||
$server->push($request->fd, 'Opened');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
接下来启动 Server,便能看到对应启动了一个 WebSocket Server 并监听于 9502 端口,此时您便可以通过各种 WebSocket Client 来进行连接和进行数据传输了。
|
||||
接下来启动 Server,便能看到对应启动了一个 WebSocket Server 并监听于 9502 端口,此时您便可以通过各种 WebSocket Client 来进行连接和数据传输了。
|
||||
|
||||
```
|
||||
$ php bin/hyperf.php start
|
||||
@ -90,6 +90,34 @@ $ php bin/hyperf.php start
|
||||
[INFO] HTTP Server listening at 0.0.0.0:9501
|
||||
```
|
||||
|
||||
!> 当我们同时监听了 HTTP Server 的 9501 端口和 WebSocket Server 的 9502 端口时, WebSocket Client 可以通过 9501 和 9502 两个端口连接 WebSocket Server,即连接 `ws://0.0.0.0:9501` 和 `ws://0.0.0.0:9502` 都可以成功。
|
||||
|
||||
因为 Swoole\WebSocket\Server 继承自 Swoole\Http\Server,可以使用 HTTP 触发所有 WebSocket 的推送,了解详情可查看 [Swoole 文档](https://wiki.swoole.com/#/websocket_server?id=websocketserver) onRequest 回调部分。
|
||||
|
||||
如需关闭,可以修改 `config/autoload/server.php` 文件给 `http` 服务中增加 `open_websocket_protocol` 配置项。
|
||||
|
||||
```php
|
||||
<?php
|
||||
return [
|
||||
// 这里省略了该文件的其它配置
|
||||
'servers' => [
|
||||
[
|
||||
'name' => 'http',
|
||||
'type' => Server::SERVER_HTTP,
|
||||
'host' => '0.0.0.0',
|
||||
'port' => 9501,
|
||||
'sock_type' => SWOOLE_SOCK_TCP,
|
||||
'callbacks' => [
|
||||
SwooleEvent::ON_REQUEST => [Hyperf\HttpServer\Server::class, 'onRequest'],
|
||||
],
|
||||
'settings' => [
|
||||
'open_websocket_protocol' => false,
|
||||
]
|
||||
],
|
||||
]
|
||||
];
|
||||
```
|
||||
|
||||
## 连接上下文
|
||||
|
||||
WebSocket 服务的 onOpen, onMessage, onClose 回调并不在同一个协程下触发,因此不能直接使用协程上下文存储状态信息。WebSocket Server 组件提供了 **连接级** 的上下文,API 与协程上下文完全一样。
|
||||
@ -109,12 +137,12 @@ use Swoole\WebSocket\Server as WebSocketServer;
|
||||
|
||||
class WebSocketController implements OnMessageInterface, OnOpenInterface
|
||||
{
|
||||
public function onMessage(WebSocketServer $server, Frame $frame): void
|
||||
public function onMessage($server, Frame $frame): void
|
||||
{
|
||||
$server->push($frame->fd, 'Username: ' . Context::get('username'));
|
||||
}
|
||||
|
||||
public function onOpen(WebSocketServer $server, Request $request): void
|
||||
public function onOpen($server, Request $request): void
|
||||
{
|
||||
Context::set('username', $request->cookie['username']);
|
||||
}
|
||||
@ -144,3 +172,54 @@ server {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 消息发送器
|
||||
|
||||
当我们想在 `HTTP` 服务中,关闭 `WebSocket` 连接时,可以直接使用 `Hyperf\WebSocketServer\Sender`。
|
||||
|
||||
`Sender` 会判断 `fd` 是否被当前 `Worker` 所持有,如果是,则会直接发送数据,如果不是,则会通过 `PipeMessage` 发送给除自己外的所有 `Worker`,然后由其他 `Worker` 进行判断,
|
||||
如果是自己持有的 `fd`,就会发送对应数据到客户端。
|
||||
|
||||
`Sender` 支持 `push` 和 `disconnect` 两个 `API`,如下:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
use Hyperf\HttpServer\Annotation\AutoController;
|
||||
use Hyperf\WebSocketServer\Sender;
|
||||
|
||||
/**
|
||||
* @AutoController
|
||||
*/
|
||||
class ServerController
|
||||
{
|
||||
/**
|
||||
* @Inject
|
||||
* @var Sender
|
||||
*/
|
||||
protected $sender;
|
||||
|
||||
public function close(int $fd)
|
||||
{
|
||||
go(function () use ($fd) {
|
||||
sleep(1);
|
||||
$this->sender->disconnect($fd);
|
||||
});
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
public function send(int $fd)
|
||||
{
|
||||
$this->sender->push($fd, 'Hello World.');
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
@ -100,7 +100,7 @@ class FooAspect extends AbstractAspect
|
||||
}
|
||||
```
|
||||
|
||||
> 注意目前的 AOP 機制尚未能直接切入 trait 的方法,您可通過使用類重寫該方法,並對使用類進行切入。
|
||||
> 2.0 版本已經可以支持切入 Trait,但要求 PHP 版本 >= 7.3。
|
||||
|
||||
## 代理類緩存
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
## 如何提交我的組件?
|
||||
|
||||
如果您開發的協程組件適配了 Hyperf,那麼您可以直接對 [hyperf/hyperf](https://github.com/hyperf/hyperf) 項目的 `master` 分支發起您的 `Pull Request`,也就是更改當前頁`(./zh-cn/awesome-components.md)`。
|
||||
如果您開發的協程組件適配了 Hyperf,那麼您可以直接對 [hyperf/hyperf](https://github.com/hyperf/hyperf) 項目的 `master` 分支發起您的 `Pull Request`,也就是更改當前頁`(zh-cn/awesome-components.md)`。
|
||||
|
||||
## 如何適配 Hyperf ?
|
||||
|
||||
@ -34,6 +34,7 @@
|
||||
|
||||
- [hyperf/database](https://github.com/hyperf/database) Hyperf 官方提供的基於 Eloquent 衍生的數據庫 ORM,可複用於其它框架
|
||||
- [hyperf/model](https://github.com/hyperf/model) Hyperf 官方提供的基於 [hyperf/database](https://github.com/hyperf/database) 組件的自動模型緩存組件
|
||||
- [reasno/fastmongo](https://github.com/Reasno/fastmongo) 基於 `hyperf/gotask` 實現的協程化 `MongoDB` 客户端
|
||||
|
||||
## 依賴注入容器
|
||||
|
||||
@ -104,6 +105,7 @@
|
||||
- [mix-php/swoolefor](https://github.com/mix-php/swoolefor) 一個由 Mixphp 實現的通用熱更新組件
|
||||
- [buexplain/go-watch](https://github.com/buexplain/go-watch) 一個基於 Go 語言實現的通用熱更新組件
|
||||
- [remy/nodemon](https://github.com/remy/nodemon) 一個基於 node.js 實現的通用熱更新組件
|
||||
- [hyperf/watcher](zh-hk/watcher.md) 適配於 `Hyperf 2.0` 的熱更新組件
|
||||
|
||||
> Warning: 請勿於生產環境使用 `熱更新/熱重載` 功能
|
||||
|
||||
|
@ -1,11 +1,122 @@
|
||||
# 版本更新記錄
|
||||
|
||||
# v2.0.4 - 2020-07-27
|
||||
|
||||
## Added
|
||||
|
||||
- [#2144](https://github.com/hyperf/hyperf/pull/2144) 數據庫查詢事件 `Hyperf\Database\Events\QueryExecuted` 添加 `$result` 字段。
|
||||
- [#2158](https://github.com/hyperf/hyperf/pull/2158) 路由 `Hyperf\HttpServer\Router\Handler` 中,添加 `$options` 字段。
|
||||
- [#2162](https://github.com/hyperf/hyperf/pull/2162) 熱更新組件添加 `Hyperf\Watcher\Driver\FindDriver`。
|
||||
- [#2169](https://github.com/hyperf/hyperf/pull/2169) `Session` 組件新增配置 `session.options.domain`,用於替換 `Request` 中獲取的 `domain`。
|
||||
- [#2174](https://github.com/hyperf/hyperf/pull/2174) 模型生成器添加 `ModelRewriteTimestampsVisitor`,用於根據數據庫字段 `created_at` 和 `updated_at`, 重寫模型字段 `$timestamps`。
|
||||
- [#2175](https://github.com/hyperf/hyperf/pull/2175) 模型生成器添加 `ModelRewriteSoftDeletesVisitor`,用於根據數據庫字段 `deleted_at`, 添加或者移除 `SoftDeletes`。
|
||||
- [#2176](https://github.com/hyperf/hyperf/pull/2176) 模型生成器添加 `ModelRewriteKeyInfoVisitor`,用於根據數據庫主鍵,重寫模型字段 `$incrementing` `$primaryKey` 和 `$keyType`。
|
||||
|
||||
## Fixed
|
||||
|
||||
- [#2149](https://github.com/hyperf/hyperf/pull/2149) 修復自定義進程運行過程中無法從 Nacos 正常更新配置的 BUG。
|
||||
- [#2159](https://github.com/hyperf/hyperf/pull/2159) 修復使用 `gen:migration` 時,由於文件已經存在導致的 `FATAL` 異常。
|
||||
|
||||
## Optimized
|
||||
|
||||
- [#2043](https://github.com/hyperf/hyperf/pull/2043) 當 `SCAN` 目錄都不存在時,拋出更加友好的異常。
|
||||
- [#2182](https://github.com/hyperf/hyperf/pull/2182) 當使用 `WebSocket` 和 `Http` 服務且 `Http` 接口被訪問時,不會記錄 `WebSocket` 關閉連接的日誌。
|
||||
|
||||
# v2.0.3 - 2020-07-20
|
||||
|
||||
## 新增
|
||||
|
||||
- [#1554](https://github.com/hyperf/hyperf/pull/1554) 新增 `hyperf/nacos` 組件。
|
||||
- [#2082](https://github.com/hyperf/hyperf/pull/2082) 監聽器 `Hyperf\Signal\Handler\WorkerStopHandler` 添加信號 `SIGINT` 監聽。
|
||||
- [#2097](https://github.com/hyperf/hyperf/pull/2097) `hyperf/filesystem` 新增 TencentCloud COS 支持.
|
||||
- [#2122](https://github.com/hyperf/hyperf/pull/2122) 添加 Trait `\Hyperf\Snowflake\Concern\HasSnowflake` 為模型自動生成雪花算法的主鍵。
|
||||
|
||||
## 修復
|
||||
|
||||
- [#2017](https://github.com/hyperf/hyperf/pull/2017) 修復 Prometheus 使用 redis 打點時,改變 label 會導致收集報錯的 BUG。
|
||||
- [#2117](https://github.com/hyperf/hyperf/pull/2117) 修復使用 `server:watch` 時,註解 `@Inject` 有時會失效的 BUG。
|
||||
- [#2123](https://github.com/hyperf/hyperf/pull/2123) 修復 `tracer` 會記錄兩次 `Redis 指令` 的 BUG。
|
||||
- [#2139](https://github.com/hyperf/hyperf/pull/2139) 修復 `ValidationMiddleware` 在 `WebSocket` 服務下使用會報錯的 BUG。
|
||||
- [#2140](https://github.com/hyperf/hyperf/pull/2140) 修復請求拋出異常時,`Session` 無法保存的 BUG。
|
||||
|
||||
## 優化
|
||||
|
||||
- [#2080](https://github.com/hyperf/hyperf/pull/2080) 方法 `Hyperf\Database\Model\Builder::paginate` 中參數 `$perPage` 的類型從 `int` 更改為 `?int`。
|
||||
- [#2110](https://github.com/hyperf/hyperf/pull/2110) 在使用 `hyperf/watcher` 時,會先檢查進程是否存在,如果不存在,才會發送 `SIGTERM` 信號。
|
||||
- [#2116](https://github.com/hyperf/hyperf/pull/2116) 優化組件 `hyperf/di` 的依賴。
|
||||
- [#2121](https://github.com/hyperf/hyperf/pull/2121) 在使用 `gen:model` 時,如果用户自定義了與數據庫字段一致的字段時,則會替換對應的 `@property`。
|
||||
- [#2129](https://github.com/hyperf/hyperf/pull/2129) 當 Response Json 格式化失敗時,會拋出更加友好的錯誤提示。
|
||||
|
||||
# v2.0.2 - 2020-07-13
|
||||
|
||||
## 修復
|
||||
|
||||
- [#1898](https://github.com/hyperf/hyperf/pull/1898) 修復定時器規則 `$min-$max` 解析有誤的 BUG。
|
||||
- [#2037](https://github.com/hyperf/hyperf/pull/2037) 修復 TCP 服務,連接後共用一個協程,導致 DB 等連接池無法正常回收連接的 BUG。
|
||||
- [#2051](https://github.com/hyperf/hyperf/pull/2051) 修復 `CoroutineServer` 不會生成 `hyperf.pid` 的 BUG。
|
||||
- [#2055](https://github.com/hyperf/hyperf/pull/1695) 修復 `Guzzle` 在傳輸大數據包時會自動添加頭 `Expect: 100-Continue`,導致請求失敗的 BUG。
|
||||
- [#2059](https://github.com/hyperf/hyperf/pull/2059) 修復 `SocketIOServer` 中 `Redis` 重連失敗的 BUG。
|
||||
- [#2067](https://github.com/hyperf/hyperf/pull/2067) 修復 `hyperf/watcher` 組件 `Syntax` 錯誤會導致進程異常。
|
||||
- [#2085](https://github.com/hyperf/hyperf/pull/2085) 修復註解 `RetryFalsy` 會導致獲得正確的結果後,再次重試。
|
||||
- [#2089](https://github.com/hyperf/hyperf/pull/2089) 修復使用 `gen:command` 後,腳本必須要進行修改,才能被加載到的 BUG。
|
||||
- [#2093](https://github.com/hyperf/hyperf/pull/2093) 修復腳本 `vendor:publish` 沒有返回碼導致報錯的 BUG。
|
||||
|
||||
## 新增
|
||||
|
||||
- [#1860](https://github.com/hyperf/hyperf/pull/1860) 為 `Server` 添加默認的 `OnWorkerExit` 回調。
|
||||
- [#2042](https://github.com/hyperf/hyperf/pull/2042) 為熱更新組件,添加文件掃描驅動。
|
||||
- [#2054](https://github.com/hyperf/hyperf/pull/2054) 為模型緩存添加 `Eager Load` 功能。
|
||||
|
||||
## 優化
|
||||
|
||||
- [#2049](https://github.com/hyperf/hyperf/pull/2049) 優化熱更新組件的 Stdout 輸出。
|
||||
- [#2090](https://github.com/hyperf/hyperf/pull/2090) 為 `hyperf/session` 組件適配非 `Hyperf` 的 `Response`。
|
||||
|
||||
## 變更
|
||||
|
||||
- [#2031](https://github.com/hyperf/hyperf/pull/2031) 常量組件的錯誤碼只支持 `int` 和 `string`。
|
||||
- [#2065](https://github.com/hyperf/hyperf/pull/2065) `WebSocket` 消息發送器 `Hyperf\WebSocketServer\Sender` 支持 `push` 和 `disconnect`。
|
||||
- [#2100](https://github.com/hyperf/hyperf/pull/2100) 組件 `hyperf/utils` 更新依賴 `doctrine/inflector` 版本到 `^2.0`。
|
||||
|
||||
## 移除
|
||||
|
||||
- [#2065](https://github.com/hyperf/hyperf/pull/2065) 移除 `Hyperf\WebSocketServer\Sender` 對方法 `send` `sendto` 和 `close` 的支持,請使用 `push` 和 `disconnect`。
|
||||
|
||||
# v2.0.1 - 2020-07-02
|
||||
|
||||
## 新增
|
||||
|
||||
- [#1934](https://github.com/hyperf/hyperf/pull/1934) 增加腳本 `gen:constant` 用於創建常量類。
|
||||
- [#1982](https://github.com/hyperf/hyperf/pull/1982) 添加熱更新組件,文件修改後自動收集註解,自動重啟。
|
||||
|
||||
## 修復
|
||||
|
||||
- [#1952](https://github.com/hyperf/hyperf/pull/1952) 修復數據庫遷移類存在時,也會生成同類名類,導致類名衝突的 BUG。
|
||||
- [#1960](https://github.com/hyperf/hyperf/pull/1960) 修復 `Hyperf\HttpServer\ResponseEmitter::isMethodsExists()` 判斷錯誤的 BUG。
|
||||
- [#1961](https://github.com/hyperf/hyperf/pull/1961) 修復因文件 `config/autoload/aspects.php` 不存在導致服務無法啟動的 BUG。
|
||||
- [#1964](https://github.com/hyperf/hyperf/pull/1964) 修復接口請求時,數據體為空會導致 `500` 錯誤的 BUG。
|
||||
- [#1965](https://github.com/hyperf/hyperf/pull/1965) 修復 `initRequestAndResponse` 失敗後,會導致請求狀態碼與實際不符的 BUG。
|
||||
- [#1968](https://github.com/hyperf/hyperf/pull/1968) 修復當修改 `aspects.php` 文件後,`Aspect` 無法安裝修改後的結果運行的 BUG。
|
||||
- [#1985](https://github.com/hyperf/hyperf/pull/1985) 修復註解全局配置不全為小寫時,會導致 `global_imports` 失敗的 BUG。
|
||||
- [#1990](https://github.com/hyperf/hyperf/pull/1990) 修復當父類存在與子類一樣的成員變量時, `@Inject` 無法正常使用的 BUG。
|
||||
- [#2019](https://github.com/hyperf/hyperf/pull/2019) 修復腳本 `gen:model` 因為使用了 `morphTo` 或 `where` 導致生成對應的 `@property` 失敗的 BUG。
|
||||
- [#2026](https://github.com/hyperf/hyperf/pull/2026) 修復當使用了魔術方法時,LazyLoad 代理生成有誤的 BUG。
|
||||
|
||||
## 變更
|
||||
|
||||
- [#1986](https://github.com/hyperf/hyperf/pull/1986) 當沒有設置正確的 `swoole.use_shortname` 變更腳本 `exit_code` 為 `SIGTERM`。
|
||||
|
||||
## 優化
|
||||
|
||||
- [#1959](https://github.com/hyperf/hyperf/pull/1959) 優化類 `ClassLoader` 可以更容易被用户繼承並修改。
|
||||
- [#2002](https://github.com/hyperf/hyperf/pull/2002) 當 `PHP` 版本大於等於 `7.3` 時,支持 `AOP` 切入 `Trait`。
|
||||
|
||||
# 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 功能的類;
|
||||
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 版本,都可以生效了;
|
||||
@ -274,7 +385,7 @@ return [
|
||||
|
||||
## 修復
|
||||
|
||||
- [#1445](https://github.com/hyperf/hyperf/pull/1445) 修復命令 `describe:route` 缺失了帶參數的路由;
|
||||
- [#1445](https://github.com/hyperf/hyperf/pull/1445) 修復命令 `describe:routes` 缺失了帶參數的路由;
|
||||
- [#1449](https://github.com/hyperf/hyperf/pull/1449) 修復了高基數請求路徑的內存溢出的問題;
|
||||
- [#1454](https://github.com/hyperf/hyperf/pull/1454) 修復 Collection 的 `flatten()` 方法因為 `INF` 參數值為 `float` 類型導致無法使用的問題;
|
||||
- [#1458](https://github.com/hyperf/hyperf/pull/1458) 修復了 Guzzle 不支持 Elasticsearch 版本大於 7.0 的問題;
|
||||
|
@ -13,7 +13,7 @@ composer require hyperf/circuit-breaker
|
||||
## 使用熔斷器
|
||||
|
||||
熔斷器的使用十分簡單,只需要加入 `Hyperf\CircuitBreaker\Annotation\CircuitBreaker` 註解,就可以根據規定策略,進行熔斷。
|
||||
比如我們需要到另外服務中查詢用户列表,用户列表需要關聯很多的表,查詢效率較低,但平常併發量不高的時候,相應速度還説得過去。一旦併發量激增,就會導致響應速度變慢,並會使對方服務出現慢查。這個時候,我們只需要配置一下熔斷超時時間 `timeout` 為 0.05 秒,失敗計數 `failCounter` 超過 1 次後熔斷,相應 `fallback` 為 `App\Service\UserService` 類的 `searchFallback` 方法。這樣當響應超時並觸發熔斷後,就不會再請求對端的服務了,而是直接將服務降級從當前項目中返回數據,即根據 `fallback` 指定的方法來進行返回。
|
||||
比如我們需要到另外服務中查詢用户列表,用户列表需要關聯很多的表,查詢效率較低,但平常併發量不高的時候,響應速度還説得過去。一旦併發量激增,就會導致響應速度變慢,並會使對方服務出現慢查。這個時候,我們只需要配置一下熔斷超時時間 `timeout` 為 0.05 秒,失敗計數 `failCounter` 超過 1 次後熔斷,相應 `fallback` 為 `App\Service\UserService` 類的 `searchFallback` 方法。這樣當響應超時並觸發熔斷後,就不會再請求對端的服務了,而是直接將服務降級從當前項目中返回數據,即根據 `fallback` 指定的方法來進行返回。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
@ -360,4 +360,80 @@ array(2) {
|
||||
|
||||
```
|
||||
|
||||
# 運行命令
|
||||
|
||||
## 命令行中運行
|
||||
|
||||
```bash
|
||||
php bin/hyperf.php foo
|
||||
```
|
||||
|
||||
## 在 Command 中運行其他命令
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use Hyperf\Command\Command as HyperfCommand;
|
||||
use Hyperf\Command\Annotation\Command;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
* @Command
|
||||
*/
|
||||
class FooCommand extends HyperfCommand
|
||||
{
|
||||
/**
|
||||
* @var ContainerInterface
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
|
||||
parent::__construct('foo');
|
||||
}
|
||||
|
||||
public function configure()
|
||||
{
|
||||
parent::configure();
|
||||
$this->setDescription('foo command');
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$this->call('bar', [
|
||||
'--foo' => 'foo'
|
||||
]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 在非 Command 中運行命令
|
||||
|
||||
```php
|
||||
$command = 'foo';
|
||||
|
||||
$params = ["command" => $command, "--foo" => "foo", "--bar" => "bar"];
|
||||
|
||||
// 可以根據自己的需求, 選擇使用的 input/output
|
||||
$input = new ArrayInput($params);
|
||||
$output = new NullOutput();
|
||||
|
||||
/** @var \Psr\Container\ContainerInterface $container */
|
||||
$container = \Hyperf\Utils\ApplicationContext::getContainer();
|
||||
|
||||
/** @var \Symfony\Component\Console\Application $application */
|
||||
$application = $container->get(\Hyperf\Contract\ApplicationInterface::class);
|
||||
$application->setAutoExit(false);
|
||||
|
||||
// 這種方式: 不會暴露出命令執行中的異常, 不會阻止程序返回
|
||||
$exitCode = $application->run($input, $output);
|
||||
|
||||
// 第二種方式: 會暴露異常, 需要自己捕捉和處理運行中的異常, 否則會阻止程序的返回
|
||||
$exitCode = $application->find($command)->run($input, $output);
|
||||
```
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
Hyperf 為您提供了分佈式系統的外部化配置支持,默認適配了:
|
||||
|
||||
- 由攜程開源的 [ctripcorp/apollo](https://github.com/ctripcorp/apollo),由 [hyper/config-apollo](https://github.com/hyperf/config-apollo) 組件提供功能支持。
|
||||
- 阿里雲提供的免費配置中心服務 [應用配置管理(ACM, Application Config Manager)](https://help.aliyun.com/product/59604.html),由 [hyper/config-aliyun-acm](https://github.com/hyperf/config-aliyun-acm) 組件提供功能支持。
|
||||
- 由攜程開源的 [ctripcorp/apollo](https://github.com/ctripcorp/apollo),由 [hyperf/config-apollo](https://github.com/hyperf/config-apollo) 組件提供功能支持。
|
||||
- 阿里雲提供的免費配置中心服務 [應用配置管理(ACM, Application Config Manager)](https://help.aliyun.com/product/59604.html),由 [hyperf/config-aliyun-acm](https://github.com/hyperf/config-aliyun-acm) 組件提供功能支持。
|
||||
|
||||
## 為什麼要使用配置中心?
|
||||
|
||||
|
@ -23,6 +23,7 @@ config
|
||||
│ ├── commands.php // 用於管理自定義命令
|
||||
│ ├── consul.php // 用於管理 Consul 客户端
|
||||
│ ├── databases.php // 用於管理數據庫客户端
|
||||
│ ├── dependencies.php // 用於管理 DI 的依賴關係和類對應關係
|
||||
│ ├── devtool.php // 用於管理開發者工具
|
||||
│ ├── exceptions.php // 用於管理異常處理器
|
||||
│ ├── listeners.php // 用於管理事件監聽者
|
||||
@ -34,7 +35,6 @@ config
|
||||
│ └── server.php // 用於管理 Server 服務
|
||||
├── config.php // 用於管理用户或框架的配置,如配置相對獨立亦可放於 autoload 文件夾內
|
||||
├── container.php // 負責容器的初始化,作為一個配置文件運行並最終返回一個 Psr\Container\ContainerInterface 對象
|
||||
├── dependencies.php // 用於管理 DI 的依賴關係和類對應關係
|
||||
└── routes.php // 用於管理路由
|
||||
```
|
||||
|
||||
|
@ -20,7 +20,7 @@ $message = ErrorCode::messages[ErrorCode::SERVER_ERROR] ?? '未知錯誤';
|
||||
|
||||
```
|
||||
|
||||
但這種實現方式並不友好,每當要查詢錯誤碼與對應錯誤信息時,都要在當前 `Class` 中搜索兩次。所以框架提供了基於註解的枚舉類。
|
||||
但這種實現方式並不友好,每當要查詢錯誤碼與對應錯誤信息時,都要在當前 `Class` 中搜索兩次,所以框架提供了基於註解的枚舉類。
|
||||
|
||||
## 安裝
|
||||
|
||||
@ -32,6 +32,14 @@ composer require hyperf/constants
|
||||
|
||||
### 定義枚舉類
|
||||
|
||||
通過 `gen:constant` 命令可以快速的生成一個枚舉類。
|
||||
|
||||
```bash
|
||||
php bin/hyperf.php gen:constant ErrorCode
|
||||
```
|
||||
|
||||
!> 此生成命令僅在 [hyperf/constants](https://github.com/hyperf/constants) 組件版本大於等於 v2.0.1 版本時可用,小於此版本時請手動創建枚舉類。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
@ -57,7 +65,6 @@ class ErrorCode extends AbstractConstants
|
||||
*/
|
||||
const SYSTEM_INVALID = 700;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
用户可以使用 `ErrorCode::getMessage(ErrorCode::SERVER_ERROR)` 來獲取對應錯誤信息。
|
||||
@ -88,7 +95,6 @@ class BusinessException extends ServerException
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### 拋出異常
|
||||
@ -112,7 +118,6 @@ class IndexController extends Controller
|
||||
throw new BusinessException(ErrorCode::SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### 可變參數
|
||||
@ -139,7 +144,6 @@ class ErrorCode extends AbstractConstants
|
||||
$message = ErrorCode::getMessage(ErrorCode::PARAMS_INVALID, ['user_id']);
|
||||
|
||||
// 1.2 版本以下 可以使用以下方式,但會在 1.2 版本移除
|
||||
|
||||
$message = ErrorCode::getMessage(ErrorCode::PARAMS_INVALID, 'user_id');
|
||||
```
|
||||
|
||||
@ -153,7 +157,7 @@ $message = ErrorCode::getMessage(ErrorCode::PARAMS_INVALID, 'user_id');
|
||||
composer require hyperf/translation
|
||||
```
|
||||
|
||||
相關配置詳見 [國際化](translation.md)
|
||||
相關配置詳見 [國際化](zh-hk/translation.md)
|
||||
|
||||
```php
|
||||
<?php
|
||||
@ -180,4 +184,3 @@ class ErrorCode extends AbstractConstants
|
||||
|
||||
$message = ErrorCode::getMessage(ErrorCode::SERVER_ERROR, ['param' => 'user_id']);
|
||||
```
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
Hyperf 是一個開源項目,一個開源項目的發展離不開開源社區的力量支持,如果您希望參與 Hyperf 的開發,可以先從 [issues](https://github.com/hyperf/hyperf/issues?page=2&q=is%3Aissue+is%3Aopen) 開始,通常來説會有以下的一些步驟:
|
||||
|
||||
1. 關注 [issues](https://github.com/hyperf/hyperf/issues?page=2&q=is%3Aissue+is%3Aopen) 的動態,評論回覆幫助提出疑問的用户;
|
||||
2. 根據 [issues](https://github.com/hyperf/hyperf/issues?page=2&q=is%3Aissue+is%3Aopen) 的內容,找尋根據自己當前對 Hyperf 的瞭解程度,去修復力所能及的 BUG 或實現功能,並以 [Pull Request](https://https://github.com/hyperf/pulls) 的形式提交至 [hyperf/hyperf](https://github.com/hyperf/hyperf) 倉庫;
|
||||
2. 根據 [issues](https://github.com/hyperf/hyperf/issues?page=2&q=is%3Aissue+is%3Aopen) 的內容,找尋根據自己當前對 Hyperf 的瞭解程度,去修復力所能及的 BUG 或實現功能,並以 [Pull Request](https://github.com/hyperf/hyperf/pulls) 的形式提交至 [hyperf/hyperf](https://github.com/hyperf/hyperf) 倉庫;
|
||||
3. 關注自己提交 Pull Request 的進度和狀態,以推動您的 Pull Request 儘快合入主倉庫;
|
||||
4. 對其他人提交的 Pull Request 進行 Code Review,並給出您的建議和看法。
|
||||
5. 根據他人或自己的需求,研發獨立的功能組件;
|
||||
|
137
docs/zh-hk/db/gen.md
Normal file
137
docs/zh-hk/db/gen.md
Normal file
@ -0,0 +1,137 @@
|
||||
# 模型創建腳本
|
||||
|
||||
Hyperf 提供了創建模型的命令,您可以很方便的根據數據表創建對應模型。命令通過 `AST` 生成模型,所以當您增加了某些方法後,也可以使用腳本方便的重置模型。
|
||||
|
||||
```bash
|
||||
php bin/hyperf.php gen:model table_name
|
||||
```
|
||||
|
||||
## 創建模型
|
||||
|
||||
可選參數如下:
|
||||
|
||||
| 參數 | 類型 | 默認值 | 備註 |
|
||||
| :----------------: | :----: | :-------------------------------: | :-----------------------------------------------: |
|
||||
| --pool | string | `default` | 連接池,腳本會根據當前連接池配置創建 |
|
||||
| --path | string | `app/Model` | 模型路徑 |
|
||||
| --force-casts | bool | `false` | 是否強制重置 `casts` 參數 |
|
||||
| --prefix | string | 空字符串 | 表前綴 |
|
||||
| --inheritance | string | `Model` | 父類 |
|
||||
| --uses | string | `Hyperf\DbConnection\Model\Model` | 配合 `inheritance` 使用 |
|
||||
| --refresh-fillable | bool | `false` | 是否刷新 `fillable` 參數 |
|
||||
| --table-mapping | array | `[]` | 為表名 -> 模型增加映射關係 比如 ['users:Account'] |
|
||||
| --ignore-tables | array | `[]` | 不需要生成模型的表名 比如 ['users'] |
|
||||
| --with-comments | bool | `false` | 是否增加字段註釋 |
|
||||
| --property-case | int | `0` | 字段類型 0 蛇形 1 駝峯 |
|
||||
|
||||
當使用 `--property-case` 將字段類型轉化為駝峯時,還需要手動在模型中加入 `Hyperf\Database\Model\Concerns\CamelCase`。
|
||||
|
||||
對應配置也可以配置到 `databases.{pool}.commands.gen:model` 中,如下
|
||||
|
||||
> 中劃線都需要轉化為下劃線
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Hyperf\Database\Commands\ModelOption;
|
||||
|
||||
return [
|
||||
'default' => [
|
||||
// 忽略其他配置
|
||||
'commands' => [
|
||||
'gen:model' => [
|
||||
'path' => 'app/Model',
|
||||
'force_casts' => true,
|
||||
'inheritance' => 'Model',
|
||||
'uses' => '',
|
||||
'refresh_fillable' => true,
|
||||
'table_mapping' => [],
|
||||
'with_comments' => true,
|
||||
'property_case' => ModelOption::PROPERTY_SNAKE_CASE,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
```
|
||||
|
||||
創建的模型如下
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Model;
|
||||
|
||||
use Hyperf\DbConnection\Model\Model;
|
||||
|
||||
/**
|
||||
* @property $id
|
||||
* @property $name
|
||||
* @property $gender
|
||||
* @property $created_at
|
||||
* @property $updated_at
|
||||
*/
|
||||
class User extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'user';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = ['id', 'name', 'gender', 'created_at', 'updated_at'];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = ['id' => 'integer', 'gender' => 'integer'];
|
||||
}
|
||||
```
|
||||
|
||||
## Visitors
|
||||
|
||||
框架提供了幾個 `Visitors`,方便用户對腳本能力進行擴展。使用方法很簡單,只需要在 `visitors` 配置中,添加對應的 `Visitor` 即可。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
'default' => [
|
||||
// 忽略其他配置
|
||||
'commands' => [
|
||||
'gen:model' => [
|
||||
'visitors' => [
|
||||
Hyperf\Database\Commands\Ast\ModelRewriteKeyInfoVisitor::class
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
```
|
||||
|
||||
### 可選 Visitors
|
||||
|
||||
- Hyperf\Database\Commands\Ast\ModelRewriteKeyInfoVisitor
|
||||
|
||||
此 `Visitor` 可以根據數據庫中主鍵,生成對應的 `$incrementing` `$primaryKey` 和 `$keyType`。
|
||||
|
||||
- Hyperf\Database\Commands\Ast\ModelRewriteSoftDeletesVisitor
|
||||
|
||||
此 `Visitor` 可以根據 `DELETED_AT` 常量判斷該模型是否含有軟刪除字段,如果存在,則添加對應的 Trait `SoftDeletes`。
|
||||
|
||||
- Hyperf\Database\Commands\Ast\ModelRewriteTimestampsVisitor
|
||||
|
||||
此 `Visitor` 可以根據 `created_at` 和 `updated_at` 自動判斷,是否啟用默認記錄 `創建和修改時間` 的功能。
|
@ -146,3 +146,47 @@ User::query(true)->where('gender', '>', 1)->delete();
|
||||
當生產環境使用了模型緩存時,如果已經建立了對應緩存數據,但此時又因為邏輯變更,添加了新的字段,並且默認值不是 `0`、`空字符`、`null` 這類數據時,就會導致在數據查詢時,從緩存中查出來的數據與數據庫中的數據不一致。
|
||||
|
||||
對於這種情況,我們可以修改 `use_default_value` 為 `true`,並添加 `Hyperf\DbConnection\Listener\InitTableCollectorListener` 到 `listener.php` 配置中,使 Hyperf 應用在啟動時主動去獲取數據庫的字段信息,並在獲取緩存數據時與之比較並進行緩存數據修正。
|
||||
|
||||
### EagerLoad
|
||||
|
||||
當我們使用模型關係時,可以通過 `load` 解決 `N+1` 的問題,但仍然需要查一次數據庫。模型緩存通過重寫了 `ModelBuilder`,可以讓用户儘可能的從緩存中拿到對應的模型。
|
||||
|
||||
> 本功能不支持 `morphTo` 和不是隻有 `whereIn` 查詢的關係模型。
|
||||
|
||||
以下提供兩種方式:
|
||||
|
||||
1. 配置 EagerLoadListener,直接使用 `loadCache` 方法。
|
||||
|
||||
修改 `listeners.php` 配置
|
||||
|
||||
```php
|
||||
return [
|
||||
Hyperf\ModelCache\Listener\EagerLoadListener::class,
|
||||
];
|
||||
```
|
||||
|
||||
通過 `loadCache` 方法,加載對應的模型關係。
|
||||
|
||||
```php
|
||||
$books = Book::findManyFromCache([1,2,3]);
|
||||
$books->loadCache(['user']);
|
||||
|
||||
foreach ($books as $book){
|
||||
var_dump($book->user);
|
||||
}
|
||||
```
|
||||
|
||||
2. 使用 EagerLoader
|
||||
|
||||
```php
|
||||
use Hyperf\ModelCache\EagerLoad\EagerLoader;
|
||||
use Hyperf\Utils\ApplicationContext;
|
||||
|
||||
$books = Book::findManyFromCache([1,2,3]);
|
||||
$loader = ApplicationContext::getContainer()->get(EagerLoader::class);
|
||||
$loader->load($books, ['user']);
|
||||
|
||||
foreach ($books as $book){
|
||||
var_dump($book->user);
|
||||
}
|
||||
```
|
||||
|
@ -19,13 +19,13 @@ $ php bin/hyperf.php db:model table_name
|
||||
可選參數如下:
|
||||
|
||||
| 參數 | 類型 | 默認值 | 備註 |
|
||||
|:------------------:|:------:|:-----------------:|:-----------------------------------------------:|
|
||||
| :----------------: | :----: | :-------------------------------: | :-----------------------------------------------: |
|
||||
| --pool | string | `default` | 連接池,腳本會根據當前連接池配置創建 |
|
||||
| --path | string | `app/Model` | 模型路徑 |
|
||||
| --force-casts | bool | `false` | 是否強制重置 `casts` 參數 |
|
||||
| --prefix | string | 空字符串 | 表前綴 |
|
||||
| --inheritance | string | `Model` | 父類 |
|
||||
| --uses | string | `App\Model\Model` | 配合 `inheritance` 使用 |
|
||||
| --uses | string | `Hyperf\DbConnection\Model\Model` | 配合 `inheritance` 使用 |
|
||||
| --refresh-fillable | bool | `false` | 是否刷新 `fillable` 參數 |
|
||||
| --table-mapping | array | `[]` | 為表名 -> 模型增加映射關係 比如 ['users:Account'] |
|
||||
| --ignore-tables | array | `[]` | 不需要生成模型的表名 比如 ['users'] |
|
||||
@ -110,7 +110,7 @@ class User extends Model
|
||||
## 模型成員變量
|
||||
|
||||
| 參數 | 類型 | 默認值 | 備註 |
|
||||
|:------------:|:------:|:-------:|:--------------------:|
|
||||
| :----------: | :----: | :-----: | :------------------: |
|
||||
| connection | string | default | 數據庫連接 |
|
||||
| table | string | 無 | 數據表名稱 |
|
||||
| primaryKey | string | id | 模型主鍵 |
|
||||
|
@ -16,6 +16,8 @@ composer require hyperf/guzzle
|
||||
composer require overtrue/flysystem-qiniu
|
||||
# 使用內存適配器時執行
|
||||
composer require league/flysystem-memory
|
||||
# 使用騰訊雲 COS 適配器時執行
|
||||
composer require overtrue/flysystem-cos
|
||||
```
|
||||
|
||||
安裝完成後,執行
|
||||
@ -128,7 +130,7 @@ return [
|
||||
|
||||
## 注意事項
|
||||
|
||||
1. S3 存儲請確認安裝 `hyperf/guzzle` 組件以提供協程化支持。阿里雲、七牛雲存儲請[開啟 Curl Hook](/zh-cn/coroutine?id=swoole-runtime-hook-level)來使用協程。因 Curl Hook 的參數支持性問題,請使用 Swoole 4.4.13 以上版本。
|
||||
1. S3 存儲請確認安裝 `hyperf/guzzle` 組件以提供協程化支持。阿里雲、七牛雲、騰訊云云存儲請[開啟 Curl Hook](/zh-cn/coroutine?id=swoole-runtime-hook-level)來使用協程。因 Curl Hook 的參數支持性問題,請使用 Swoole 4.4.13 以上版本。
|
||||
2. minIO, ceph radosgw 等私有對象存儲方案均支持 S3 協議,可以使用 S3 適配器。
|
||||
3. 使用 Local 驅動時,根目錄是配置好的地址,而不是操作系統的根目錄。例如,Local 驅動 `root` 設置為 `/var/www`, 則本地磁盤上的 `/var/www/public/file.txt` 通過 flysystem API 訪問時應使用 `/public/file.txt` 或 `public/file.txt` 。
|
||||
4. 以阿里雲 OSS 為例,1 核 1 進程讀操作性能對比:
|
||||
@ -241,6 +243,21 @@ return [
|
||||
'bucket' => env('QINIU_BUCKET'),
|
||||
'domain' => env('QINIU_DOMAIN'),
|
||||
],
|
||||
'cos' => [
|
||||
'driver' => \Hyperf\Filesystem\Adapter\CosAdapterFactory::class,
|
||||
'region' => env('COS_REGION'),
|
||||
'credentials' => [
|
||||
'appId' => env('COS_APPID'),
|
||||
'secretId' => env('COS_SECRET_ID'),
|
||||
'secretKey' => env('COS_SECRET_KEY'),
|
||||
],
|
||||
'bucket' => env('COS_BUCKET'),
|
||||
'read_from_cdn' => false,
|
||||
// 'timeout' => 60,
|
||||
// 'connect_timeout' => 60,
|
||||
// 'cdn' => '',
|
||||
// 'scheme' => 'https',
|
||||
],
|
||||
],
|
||||
];
|
||||
```
|
||||
|
@ -38,7 +38,7 @@ message HiReply {
|
||||
- 使用 protoc 生成示例代碼
|
||||
|
||||
```
|
||||
# 使用 linux 包管理工具安裝 protoc, 下面以 alpine 為例, 也可以參考 hyper-skeleton 下的 Dockerfile
|
||||
# 使用 linux 包管理工具安裝 protoc, 下面以 alpine 為例, 也可以參考 hyperf-skeleton 下的 Dockerfile
|
||||
apk add protobuf
|
||||
|
||||
# 使用 protoc 自動生成代碼
|
||||
@ -157,7 +157,7 @@ class HiClient extends BaseClient
|
||||
{
|
||||
public function sayHello(HiUser $argument)
|
||||
{
|
||||
return $this->simpleRequest(
|
||||
return $this->_simpleRequest(
|
||||
'/grpc.hi/sayHello',
|
||||
$argument,
|
||||
[HiReply::class, 'decode']
|
||||
|
@ -405,6 +405,6 @@ Router::get('/metrics', function(){
|
||||
|
||||
> 本節只適用於 Prometheus 驅動
|
||||
|
||||
如果您啟用了默認指標,`Hyperf/Metric` 為您準備了一個開箱即用的 Grafana 控制枱。下載控制枱 [json 文件](https://raw.githubusercontent.com/hyperf/hyperf/master/src/metric/grafana.json),導入 Grafana 中即可使用。
|
||||
如果您啟用了默認指標,`Hyperf/Metric` 為您準備了一個開箱即用的 Grafana 控制枱。下載控制枱 [json 文件](https://cdn.jsdelivr.net/gh/hyperf/hyperf/src/metric/grafana.json),導入 Grafana 中即可使用。
|
||||
|
||||
![grafana](imgs/grafana.png)
|
||||
|
130
docs/zh-hk/nacos.md
Normal file
130
docs/zh-hk/nacos.md
Normal file
@ -0,0 +1,130 @@
|
||||
# Nacos
|
||||
|
||||
一個 `Nacos` 的 `PHP` 協程客户端,與 `Hyperf` 的配置中心、微服務治理完美結合。
|
||||
|
||||
## 安裝
|
||||
|
||||
```shell
|
||||
composer require hyperf/nacos
|
||||
```
|
||||
|
||||
### 發佈配置文件
|
||||
|
||||
```shell
|
||||
php bin/hyperf.php vendor:publish hyperf/nacos
|
||||
```
|
||||
|
||||
### 目錄結構
|
||||
|
||||
```
|
||||
./src
|
||||
├── Api
|
||||
│ ├── AbstractNacos.php
|
||||
│ ├── NacosConfig.php
|
||||
│ ├── NacosInstance.php
|
||||
│ ├── NacosOperator.php
|
||||
│ └── NacosService.php
|
||||
├── Client.php
|
||||
├── Config
|
||||
│ ├── FetchConfigProcess.php
|
||||
│ ├── OnPipeMessageListener.php
|
||||
│ └── PipeMessage.php
|
||||
├── ConfigProvider.php
|
||||
├── Contract
|
||||
│ └── LoggerInterface.php
|
||||
├── Exception
|
||||
│ ├── InvalidArgumentException.php
|
||||
│ ├── NacosThrowable.php
|
||||
│ └── RuntimeException.php
|
||||
├── Instance.php
|
||||
├── Listener
|
||||
│ ├── MainWorkerStartListener.php
|
||||
│ └── OnShutdownListener.php
|
||||
├── Model
|
||||
│ ├── AbstractModel.php
|
||||
│ ├── ConfigModel.php
|
||||
│ ├── InstanceModel.php
|
||||
│ └── ServiceModel.php
|
||||
├── Process
|
||||
│ └── InstanceBeatProcess.php
|
||||
└── Service.php
|
||||
```
|
||||
|
||||
## 服務與實例
|
||||
|
||||
`MainWorkerStartListener.php` 將在系統啟動完成時自動完成 `實例註冊`,`服務註冊`
|
||||
|
||||
如果需要在服務下線時自動註銷服務,請增加如下配置,以監聽 `Shutdown` 事件
|
||||
|
||||
```php
|
||||
// config/autoload/server.php
|
||||
|
||||
return [
|
||||
// ...other
|
||||
'callbacks' => [
|
||||
// ...other
|
||||
SwooleEvent::ON_SHUTDOWN => [Hyperf\Framework\Bootstrap\ShutdownCallback::class, 'onShutdown']
|
||||
]
|
||||
];
|
||||
```
|
||||
|
||||
### 獲取當前實例
|
||||
|
||||
```php
|
||||
$instance = new \Hyperf\Nacos\Instance();
|
||||
```
|
||||
|
||||
### 獲取當前服務
|
||||
|
||||
```php
|
||||
$service = new \Hyperf\Nacos\Service();
|
||||
```
|
||||
|
||||
### 獲取一個服務的最優節點
|
||||
|
||||
```php
|
||||
$instance = make(NacosInstance::class);
|
||||
|
||||
$service = new ServiceModel([
|
||||
'service_name' => 'hyperf',
|
||||
'group_name' => 'api',
|
||||
'namespace_id' => '5ce9d1c1-6732-4ccc-ae1f-5139af86a845'
|
||||
]);
|
||||
|
||||
$optimal = $instance->getOptimal($service);
|
||||
|
||||
```
|
||||
|
||||
## 配置中心
|
||||
|
||||
`MainWorkerStartListener.php` 系統啟動時將拉取遠程配置, 併合入`hyperf` 的 `Config`
|
||||
|
||||
`FetchConfigProcess.php` 自定義進程將監聽配置, 若有更新將發送 `PipeMessage` 到各服務`worker` 進程, 併合入當前進程的 `Config`
|
||||
|
||||
如果服務如下配置
|
||||
```php
|
||||
// config/autoload/nacos.php
|
||||
|
||||
return [
|
||||
// ...other
|
||||
'config_reload_interval' => 3,
|
||||
// 遠程配置合併節點, 默認 config 根節點
|
||||
'config_append_node' => 'nacos_config',
|
||||
'listener_config' => [
|
||||
// 配置項 dataId, group, tenant, type, content
|
||||
[
|
||||
'data_id' => 'hyperf-service-config',
|
||||
'group' => 'DEFAULT_GROUP',
|
||||
],
|
||||
[
|
||||
'data_id' => 'hyperf-service-config-yml',
|
||||
'group' => 'DEFAULT_GROUP',
|
||||
'type' => 'yml',
|
||||
],
|
||||
],
|
||||
];
|
||||
```
|
||||
|
||||
系統將自動監聽`listener_config` 中的配置,並將其合併入`hyperf Config` 對象的指定(`config_append_node`) 節點,可以用`config('nacos_config.***')` 獲取,若沒有配置 `config_append_node` 項,將會併入 `Config` 對象根節點。
|
||||
|
||||
> 所有配置的 `鍵(key)` 在實際發起 API 請求時會自動從下劃線風格轉換為駝峯風格。
|
@ -8,4 +8,21 @@
|
||||
|
||||
## 通過容器獲取的類都是單例
|
||||
|
||||
通過依賴注入容器獲取的都是進程內持久化的,是多個協程共享的,所以不能包含任何的請求唯一的數據或協程唯一的數據,這類型的數據都通過協程上下文去處理,具體請仔細閲讀 [依賴注入](./zh-hk/di.md) 和 [協程](./zh-hk/coroutine.md) 章節。
|
||||
通過依賴注入容器獲取的都是進程內持久化的,是多個協程共享的,所以不能包含任何的請求唯一的數據或協程唯一的數據,這類型的數據都通過協程上下文去處理,具體請仔細閲讀 [依賴注入](zh-hk/di.md) 和 [協程](zh-hk/coroutine.md) 章節。
|
||||
|
||||
## 項目部署
|
||||
|
||||
> 官方的 Dockerfile 已經完成了以下操作。
|
||||
|
||||
線上代碼部署時,請務必開啟 `scan_cacheable`。
|
||||
|
||||
開啟此配置後,首次掃描時會生成代理類和註解緩存,再次啟動時,則可以直接使用緩存,極大優化內存使用率和啟動速度。因為跳過了掃描階段,所以會依賴 `Composer Class Map`,故我們必須要執行 `--optimize-autoloader` 優化索引。
|
||||
|
||||
綜上,線上更新代碼,重啟項目前,需要執行以下命令
|
||||
|
||||
```bash
|
||||
# 優化 Composer 索引
|
||||
composer dump-autoload -o
|
||||
# 生成代理類和註解緩存
|
||||
php bin/hyperf.php
|
||||
```
|
||||
|
@ -35,7 +35,7 @@ composer create-project hyperf/hyperf-skeleton
|
||||
|
||||
```
|
||||
# 下載並運行 hyperf/hyperf 鏡像,並將鏡像內的項目目錄綁定到宿主機的 /tmp/skeleton 目錄
|
||||
docker run -v /tmp/skeleton:/hyperf-skeleton -p 9501:9501 -it --entrypoint /bin/sh hyperf/hyperf:7.2-alpine-cli
|
||||
docker run -v /tmp/skeleton:/hyperf-skeleton -p 9501:9501 -it --entrypoint /bin/sh hyperf/hyperf:latest
|
||||
|
||||
# 鏡像容器運行後,在容器內安裝 Composer
|
||||
wget https://github.com/composer/composer/releases/download/1.8.6/composer.phar
|
||||
|
@ -230,7 +230,7 @@ class IndexController
|
||||
> Tips: 您也可以將啟動 Server 的命令配置在 IDE 上,便可直接通過 IDE 的 `啟動/停止` 操作快捷的完成 `啟動服務` 或 `重啟服務` 的操作。
|
||||
> 且非視圖開發時可以採用 [TDD(Test-Driven Development)](https://baike.baidu.com/item/TDD/9064369) 測試驅動開發來進行開發,這樣不僅可以省略掉服務重啟和頻繁切換窗口的麻煩,還可保證接口數據的正確性。
|
||||
|
||||
> 另外,在文檔 [協程組件庫](./zh-hk/awesome-components?id=%e7%83%ad%e6%9b%b4%e6%96%b0%e7%83%ad%e9%87%8d%e8%bd%bd) 一章中提供了多種由社區開發者支持的 熱更新/熱重載 的解決方案,如仍希望採用 熱更新/熱重載 方案可再深入瞭解。
|
||||
> 另外,在文檔 [協程組件庫](zh-hk/awesome-components?id=%e7%83%ad%e6%9b%b4%e6%96%b0%e7%83%ad%e9%87%8d%e8%bd%bd) 一章中提供了多種由社區開發者支持的 熱更新/熱重載 的解決方案,如仍希望採用 熱更新/熱重載 方案可再深入瞭解。
|
||||
|
||||
## 多端口監聽
|
||||
|
||||
|
@ -1,5 +1,82 @@
|
||||
# 常見問題
|
||||
|
||||
## `Inject` 或 `Value` 註解不生效
|
||||
|
||||
`2.0` 使用了構造函數中注入 `Inject` 和 `Value` 的功能,以下兩種場景,可能會導致注入失效,請注意使用。
|
||||
|
||||
1. 原類沒有使用 `Inject` 或 `Value`,但父類使用了 `Inject` 或 `Value`,且原類寫了構造函數,同時又沒有調用父類構造函數的情況。
|
||||
|
||||
這樣就會導致原類不會生成代理類,而實例化的時候又調用了自身的構造函數,故沒辦法執行到父類的構造函數。
|
||||
所以父類代理類中的方法 `__handlePropertyHandler` 就不會執行,那麼 `Inject` 或 `Value` 註解就不會生效。
|
||||
|
||||
```php
|
||||
class ParentClass {
|
||||
/**
|
||||
* @Inject
|
||||
* @var Service
|
||||
*/
|
||||
protected $value;
|
||||
}
|
||||
|
||||
class Origin extends ParentClass
|
||||
{
|
||||
public function __construct() {}
|
||||
}
|
||||
```
|
||||
|
||||
2. 原類沒有使用 `Inject` 或 `Value`,但 `Trait` 中使用了 `Inject` 或 `Value`。
|
||||
|
||||
這樣就會導致原類不會生成代理類,故沒辦法執行構造函數裏的 `__handlePropertyHandler`,所以 `Trait` 的 `Inject` 或 `Value` 註解就不會生效。
|
||||
|
||||
```php
|
||||
trait OriginTrait {
|
||||
/**
|
||||
* @Inject
|
||||
* @var Service
|
||||
*/
|
||||
protected $value;
|
||||
}
|
||||
|
||||
class Origin
|
||||
{
|
||||
use OriginTrait;
|
||||
}
|
||||
```
|
||||
|
||||
基於上述兩種情況,可見 `原類` 是否生成代理類至關重要,所以,如果使用了帶有 `Inject` 或 `Value` 的 `Trait` 和 `父類` 時,給原類添加一個 `Inject`,即可解決上述兩種情況。
|
||||
|
||||
```php
|
||||
|
||||
use Hyperf\Contract\StdoutLoggerInterface;
|
||||
|
||||
trait OriginTrait {
|
||||
/**
|
||||
* @Inject
|
||||
* @var Service
|
||||
*/
|
||||
protected $trait;
|
||||
}
|
||||
|
||||
class ParentClass {
|
||||
/**
|
||||
* @Inject
|
||||
* @var Service
|
||||
*/
|
||||
protected $value;
|
||||
}
|
||||
|
||||
class Origin extends ParentClass
|
||||
{
|
||||
use OriginTrait;
|
||||
|
||||
/**
|
||||
* @Inject
|
||||
* @var StdoutLoggerInterface
|
||||
*/
|
||||
protected $logger;
|
||||
}
|
||||
```
|
||||
|
||||
## Swoole 短名未關閉
|
||||
|
||||
```
|
||||
@ -8,18 +85,6 @@
|
||||
|
||||
您需要在您的 php.ini 配置文件增加 `swoole.use_shortname = 'Off'` 配置項
|
||||
|
||||
如果您使用的是 1.0.x 版本,這也可能是因為你按以下的方式設置了
|
||||
|
||||
```
|
||||
// 在 1.0 系列版本下
|
||||
// 這些都是錯誤的,注意 `大小寫` 和 `引號`
|
||||
swoole.use_shortname = 'off'
|
||||
swoole.use_shortname = off
|
||||
swoole.use_shortname = Off
|
||||
// 下面的才是正確的
|
||||
swoole.use_shortname = 'Off'
|
||||
```
|
||||
|
||||
> 注意該配置必須於 php.ini 內配置,無法通過 ini_set() 函數來重寫
|
||||
|
||||
當然,也可以通過以下的命令來啟動服務,在執行 PHP 命令時關閉掉 Swoole 短名功能
|
||||
@ -28,40 +93,6 @@ swoole.use_shortname = 'Off'
|
||||
php -d swoole.use_shortname=Off bin/hyperf.php start
|
||||
```
|
||||
|
||||
## 代理類緩存
|
||||
|
||||
代理類緩存一旦生成,將不會再重新覆蓋。所以當你修改了已經生成代理類的文件時,需要手動清理。
|
||||
|
||||
代理類位置如下
|
||||
|
||||
```
|
||||
runtime/container/proxy/
|
||||
```
|
||||
|
||||
重新生成緩存命令,新緩存會覆蓋原目錄
|
||||
|
||||
```bash
|
||||
vendor/bin/init-proxy.sh
|
||||
```
|
||||
|
||||
刪除代理類緩存
|
||||
|
||||
```bash
|
||||
rm -rf ./runtime/container/proxy
|
||||
```
|
||||
|
||||
所以單測命令可以使用以下代替:
|
||||
|
||||
```bash
|
||||
vendor/bin/init-proxy.sh && composer test
|
||||
```
|
||||
|
||||
同理,啟動命令可以使用以下代替
|
||||
|
||||
```bash
|
||||
vendor/bin/init-proxy.sh && php bin/hyperf.php start
|
||||
```
|
||||
|
||||
## 異步隊列消息丟失
|
||||
|
||||
如果在使用 `async-queue` 組件時,發現 `handle` 中的方法沒有執行,請先檢查以下幾種情況:
|
||||
@ -74,29 +105,26 @@ vendor/bin/init-proxy.sh && php bin/hyperf.php start
|
||||
1. killall php
|
||||
2. 修改 `async-queue` 配置 `channel`
|
||||
|
||||
## 1.1.24 - 1.1.26 版本 SymfonyEventDispatcher 報錯
|
||||
|
||||
因為 `symfony/console` 默認使用的 `^4.2` 版本,而 `symfony/event-dispatcher` 的 `^4.3` 版本與 `<4.3` 版本不兼容。
|
||||
|
||||
`hyperf/framework` 默認推薦使用 `^4.3` 版本的 `symfony/event-dispatcher`,就有一定概率導致實現上的衝突。
|
||||
|
||||
如果有類似的情況出現,可以嘗試以下操作
|
||||
|
||||
```
|
||||
rm -rf vendor
|
||||
rm -rf composer.lock
|
||||
composer require "symfony/event-dispatcher:^4.3"
|
||||
```
|
||||
|
||||
1.1.27 版本中,會在 `composer.json` 中添加以下配置,來處理這個問題。
|
||||
|
||||
```
|
||||
"conflict": {
|
||||
"symfony/event-dispatcher": "<4.3"
|
||||
},
|
||||
```
|
||||
|
||||
## 使用 AMQP 組件報 `Swoole\Error: API must be called in the coroutine` 錯誤
|
||||
|
||||
可以在 `config/autoload/amqp.php` 配置文件中將 `close_on_destruct` 改為 `false` 即可。
|
||||
|
||||
## 使用 Swoole 4.5 版本和 view 組件時訪問接口出現 404
|
||||
|
||||
使用 Swoole 4.5 版本和 view 組件如果出現接口 404 的問題,可以嘗試刪除 `config/autoload/server.php` 文件中的 `static_handler_locations` 配置項。
|
||||
|
||||
此配置下的路徑都會被認為是靜態文件路由,所以如果配置了`/`,就會導致所有接口都會被認為是文件路徑,導致接口 404。
|
||||
|
||||
## 代碼不生效
|
||||
|
||||
當碰到修改後的代碼不生效的問題,請執行以下命令
|
||||
|
||||
```bash
|
||||
composer dump-autoload -o
|
||||
```
|
||||
|
||||
開發階段,請不要設置 `scan_cacheable` 為 `true`,它會導致 `收集器緩存` 存在時,不會再次掃描文件。另外,官方骨架包中的 `Dockerfile` 是默認開啟這個配置的,`Docker` 環境下開發的同學,請注意這裏。
|
||||
|
||||
> 當環境變量存在 SCAN_CACHEABLE 時,.env 中無法修改這個配置。
|
||||
|
||||
`2.0.0` 和 `2.0.1` 兩個版本,判斷文件是否修改時,沒有判斷修改時間相等的情況,所以文件修改後,立馬生成緩存的情況(比如使用 `watcher` 組件時), 會導致代碼無法及時生效。
|
||||
|
@ -37,7 +37,7 @@ ReactiveX 是 Reactive Extensions 的縮寫,一般簡寫為 Rx,最初是 LIN
|
||||
## 安裝
|
||||
|
||||
```bash
|
||||
composer require hyper/reactive-x
|
||||
composer require hyperf/reactive-x
|
||||
```
|
||||
|
||||
## 封裝
|
||||
|
@ -15,5 +15,5 @@
|
||||
|
||||
## 版本迭代週期
|
||||
|
||||
Hyperf 採用敏捷開發模式,每週一個迭代計劃,並於 `每週的星期四 (UTC/GMT+08:00)` 發佈一個版本,通常來説是一個 z 版本的發佈,也有可能是一個 y 版本。而對於 x 版本,則會根據實際的研究成果情況而決定具體的迭代計劃和時間。
|
||||
Hyperf 採用敏捷開發模式,每週一個迭代計劃,並於 `每週的星期一 (UTC/GMT+08:00)` 發佈一個版本,通常來説是一個 z 版本的發佈,也有可能是一個 y 版本。而對於 x 版本,則會根據實際的研究成果情況而決定具體的迭代計劃和時間。
|
||||
關於 Hyperf 採用的版本規則,請查閲 [版本説明](zh-hk/versions.md) 一章。
|
||||
|
@ -208,4 +208,4 @@ public function index(RequestInterface $request)
|
||||
## HTTP 異常
|
||||
|
||||
在路由匹配不到路由時,如 `路由找不到(404)`、`請求方法不允許(405)` 等 HTTP 異常,Hyperf 會統一拋出一個 `Hyperf\HttpMessage\Exception\HttpException` 異常類的子類,您需要通過 ExceptionHandler 機制來管理這些異常並做對應的響應處理,默認情況下可以直接使用組件提供的 `Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler` 來進行異常捕獲處理,注意這個異常處理器需要您自行配置到 `config/autoload/exceptions.php` 配置文件中去,並保障多個異常處理器之間的順序鏈路是正確的。
|
||||
當您需要對 `路由找不到(404)`、`請求方法不允許(405)` 等 HTTP 異常情況的響應進行自定義處理時,您可直接根據 `HttpExceptionHandler` 的代碼實現您自己的異常處理器,並配置您自己的異常處理器。關於異常處理器的邏輯和使用説明,可具體查閲 [異常處理](./zh-hk/exception-handler.md)
|
||||
當您需要對 `路由找不到(404)`、`請求方法不允許(405)` 等 HTTP 異常情況的響應進行自定義處理時,您可直接根據 `HttpExceptionHandler` 的代碼實現您自己的異常處理器,並配置您自己的異常處理器。關於異常處理器的邏輯和使用説明,可具體查閲 [異常處理](zh-hk/exception-handler.md)
|
||||
|
@ -70,10 +70,14 @@ use Symfony\Component\HttpFoundation\Request;
|
||||
$get = $this->request->getQueryParams();
|
||||
$post = $this->request->getParsedBody();
|
||||
$cookie = $this->request->getCookieParams();
|
||||
$files = $this->request->getUploadedFiles();
|
||||
$uploadFiles = $this->request->getUploadedFiles() ?? [];
|
||||
$server = $this->request->getServerParams();
|
||||
$xml = $this->request->getBody()->getContents();
|
||||
|
||||
$files = [];
|
||||
/** @var \Hyperf\HttpMessage\Upload\UploadedFile $v */
|
||||
foreach ($uploadFiles as $k => $v) {
|
||||
$files[$k] = $v->toArray();
|
||||
}
|
||||
$app['request'] = new Request($get, $post, [], $cookie, $files, $server, $xml);
|
||||
|
||||
// Do something...
|
||||
@ -90,7 +94,7 @@ $app['request'] = new Request($get,$post,[],$cookie,$files,$server,$xml);
|
||||
```php
|
||||
$response = $app->server->serve();
|
||||
|
||||
return $response->getBody()->getContents();
|
||||
return $response->getContent();
|
||||
```
|
||||
|
||||
## 如何替換緩存
|
||||
|
@ -10,7 +10,7 @@ composer require hyperf/service-governance
|
||||
|
||||
# 註冊服務
|
||||
|
||||
註冊服務可通過 `@RpcService` 註解對一個類進行定義,即為發佈這個服務了,目前 Hyperf 僅適配了 JSON RPC 協議,具體內容也可到 [JSON RPC 服務](./zh-hk/json-rpc.md) 章節瞭解詳情。
|
||||
註冊服務可通過 `@RpcService` 註解對一個類進行定義,即為發佈這個服務了,目前 Hyperf 僅適配了 JSON RPC 協議,具體內容也可到 [JSON RPC 服務](zh-hk/json-rpc.md) 章節瞭解詳情。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
@ -8,6 +8,14 @@
|
||||
composer require hyperf/signal
|
||||
```
|
||||
|
||||
## 發佈配置
|
||||
|
||||
您可以通過下面的命令來發布默認的配置文件到您的項目中:
|
||||
|
||||
```bash
|
||||
php bin/hyperf.php vendor:publish hyperf/signal
|
||||
```
|
||||
|
||||
## 添加處理器
|
||||
|
||||
以下我們監聽 `Worker` 進程的 `SIGTERM` 信號,當收到信號後,打印出信號值。
|
||||
@ -42,7 +50,7 @@ class TermSignalHandler implements SignalHandlerInterface
|
||||
|
||||
```
|
||||
|
||||
因為 Worker 進程 SIGTERM 信號被捕獲後,無法正常退出,所以用户可以直接 Ctrl+C 退出,或者修改 signal.php 配置
|
||||
因為 Worker 進程接收的 SIGTERM 信號被捕獲後,無法正常退出,所以用户可以直接 `Ctrl + C` 退出,或者修改 `config/autoload/signal.php` 配置,如下:
|
||||
|
||||
```php
|
||||
<?php
|
||||
@ -55,7 +63,6 @@ return [
|
||||
],
|
||||
'timeout' => 5.0,
|
||||
];
|
||||
|
||||
```
|
||||
|
||||
`WorkerStopHandler` 觸發後,會在 `max_wait_time` 時間後,關掉當前進程。
|
||||
`WorkerStopHandler` 觸發後,會在所設置的 [max_wait_time](https://wiki.swoole.com/#/server/setting?id=max_wait_time) 配置時間後,關閉掉當前進程。
|
||||
|
@ -138,3 +138,17 @@ $userId = 20190620;
|
||||
$id = $generator->generate($userId);
|
||||
|
||||
```
|
||||
|
||||
## 在數據庫模型中應用
|
||||
|
||||
配置好 Snowflake 以後,我們可以讓數據庫模型直接使用雪花 id 作為主鍵。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
class User extends \Hyperf\Database\Model\Model {
|
||||
use \Hyperf\Snowflake\Concern\Snowflake;
|
||||
}
|
||||
```
|
||||
|
||||
上述 User 模型在創建時便會默認使用 Snowflake 算法生成主鍵。
|
||||
|
@ -52,6 +52,7 @@
|
||||
* [快速開始](zh-hk/db/quick-start.md)
|
||||
* [查詢構造器](zh-hk/db/querybuilder.md)
|
||||
* [模型](zh-hk/db/model.md)
|
||||
* [創建腳本](zh-hk/db/gen.md)
|
||||
* [模型關係](zh-hk/db/relationship.md)
|
||||
* [查詢分頁](zh-hk/db/paginator.md)
|
||||
* [模型事件](zh-hk/db/event.md)
|
||||
@ -72,6 +73,7 @@
|
||||
* [調用鏈追蹤](zh-hk/tracer.md)
|
||||
* [服務監控](zh-hk/metric.md)
|
||||
* [服務重試](zh-hk/retry.md)
|
||||
* [Nacos](zh-hk/nacos.md)
|
||||
|
||||
* 消息隊列
|
||||
|
||||
@ -103,6 +105,7 @@
|
||||
* [重試](zh-hk/retry.md)
|
||||
* [信號處理器](zh-hk/signal.md)
|
||||
* [ReactiveX](zh-hk/reactive-x.md)
|
||||
* [Watcher](zh-hk/watcher.md)
|
||||
|
||||
* 應用部署
|
||||
|
||||
|
@ -217,7 +217,7 @@ return [
|
||||
'arguments' => 'arguments',
|
||||
'result' => 'result',
|
||||
],
|
||||
// 數據庫客户端 (hyper/database)
|
||||
// 數據庫客户端 (hyperf/database)
|
||||
'db' => [
|
||||
'db.query' => 'db.query',
|
||||
'db.statement' => 'db.statement',
|
||||
|
@ -245,6 +245,12 @@ return [
|
||||
];
|
||||
```
|
||||
|
||||
## 啟動服務並測試訪問接口
|
||||
|
||||
使用 Swoole 4.5 版本和 view 組件如果出現接口 404 的問題,可以嘗試刪除 `config/autoload/server.php` 文件中的 `static_handler_locations` 配置項。
|
||||
|
||||
此配置下的路徑都會被認為是靜態文件路由,所以如果配置了`/`,就會導致所有接口都會被認為是文件路徑,導致接口 404。
|
||||
|
||||
## 完成升級
|
||||
|
||||
至此,2.0 版本升級即已完成,但由於 Hyperf 的各個底層文件都是可以通過 DI 來實現重寫的,如您重寫了某些本次升級調整到了的框架內部文件,您仍需再根據您的實際情況進行一定的調整。
|
||||
|
72
docs/zh-hk/watcher.md
Normal file
72
docs/zh-hk/watcher.md
Normal file
@ -0,0 +1,72 @@
|
||||
# 熱更新 Watcher
|
||||
|
||||
自從 `2.0` 版本使用了 `BetterReflection` 來收集掃描目錄內的 `語法樹` 和 `反射數據`,導致掃描速度相較 `1.1` 慢了不少。
|
||||
|
||||
> 首次啟動,因為沒有任何緩存,所以會比較慢,當二次啟動時,會按照文件修改時間,進行動態收集,但因為仍需要實例化 `BetterReflection`,所以啟動時間仍然比較長。
|
||||
|
||||
`Watcher` 組件除了解決上述啟動問題,還提供了文件修改後立馬重啟的功能。
|
||||
|
||||
## 安裝
|
||||
|
||||
```
|
||||
composer require hyperf/watcher --dev
|
||||
```
|
||||
|
||||
## 配置
|
||||
|
||||
### 發佈配置
|
||||
|
||||
```bash
|
||||
php bin/hyperf.php vendor:publish hyperf/watcher
|
||||
```
|
||||
|
||||
### 配置説明
|
||||
|
||||
| 配置 | 默認值 | 備註 |
|
||||
| :------------: | :--------------: | :-------------------------------------------------------: |
|
||||
| driver | `ScanFileDriver` | 默認定時掃描文件驅動 |
|
||||
| bin | `php` | 用於啟動服務的腳本 例如 `php -d swoole.use_shortname=Off` |
|
||||
| watch.dir | `app`, `config` | 監聽目錄 |
|
||||
| watch.file | `.env` | 監聽文件 |
|
||||
| watch.interval | `2000` | 掃描間隔(毫秒) |
|
||||
|
||||
## 支持驅動
|
||||
|
||||
| 驅動 | 備註 |
|
||||
| :----------------------------------: | :---------------------------------: |
|
||||
| Hyperf\Watcher\Driver\ScanFileDriver | 無需擴展 |
|
||||
| Hyperf\Watcher\Driver\FswatchDriver | 需要安裝 fswatch |
|
||||
| Hyperf\Watcher\Driver\FindDriver | 需要安裝 find,MAC 下需要安裝 gfind |
|
||||
|
||||
### `fswatch` 安裝
|
||||
|
||||
Mac
|
||||
|
||||
```bash
|
||||
brew install fswatch
|
||||
```
|
||||
|
||||
其他
|
||||
|
||||
```bash
|
||||
wget https://github.com/emcrisostomo/fswatch/releases/download/1.14.0/fswatch-1.14.0.tar.gz \
|
||||
&& tar -xf fswatch-1.14.0.tar.gz \
|
||||
&& cd fswatch-1.14.0/ \
|
||||
&& ./configure \
|
||||
&& make \
|
||||
&& make install
|
||||
```
|
||||
|
||||
## 啟動
|
||||
|
||||
因為目錄的關係,需要在項目根目錄中運行。
|
||||
|
||||
```bash
|
||||
php bin/hyperf.php server:watch
|
||||
```
|
||||
|
||||
## 不足
|
||||
- 暫時 Alpine Docker 環境下,稍微有點問題,後續會完善。
|
||||
- 刪除文件需要手動重啟才能生效。
|
||||
- vendor 中的文件需要使用 classmap 形式自動加載才能被掃描。(即執行`composer dump-autoload -o`)
|
||||
|
@ -63,17 +63,17 @@ use Swoole\WebSocket\Server as WebSocketServer;
|
||||
|
||||
class WebSocketController implements OnMessageInterface, OnOpenInterface, OnCloseInterface
|
||||
{
|
||||
public function onMessage(WebSocketServer $server, Frame $frame): void
|
||||
public function onMessage($server, Frame $frame): void
|
||||
{
|
||||
$server->push($frame->fd, 'Recv: ' . $frame->data);
|
||||
}
|
||||
|
||||
public function onClose(Server $server, int $fd, int $reactorId): void
|
||||
public function onClose($server, int $fd, int $reactorId): void
|
||||
{
|
||||
var_dump('closed');
|
||||
}
|
||||
|
||||
public function onOpen(WebSocketServer $server, Request $request): void
|
||||
public function onOpen($server, Request $request): void
|
||||
{
|
||||
$server->push($request->fd, 'Opened');
|
||||
}
|
||||
@ -109,12 +109,12 @@ use Swoole\WebSocket\Server as WebSocketServer;
|
||||
|
||||
class WebSocketController implements OnMessageInterface, OnOpenInterface
|
||||
{
|
||||
public function onMessage(WebSocketServer $server, Frame $frame): void
|
||||
public function onMessage($server, Frame $frame): void
|
||||
{
|
||||
$server->push($frame->fd, 'Username: ' . Context::get('username'));
|
||||
}
|
||||
|
||||
public function onOpen(WebSocketServer $server, Request $request): void
|
||||
public function onOpen($server, Request $request): void
|
||||
{
|
||||
Context::set('username', $request->cookie['username']);
|
||||
}
|
||||
@ -144,3 +144,54 @@ server {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 消息發送器
|
||||
|
||||
當我們想在 `HTTP` 服務中,關閉 `WebSocket` 連接時,可以直接使用 `Hyperf\WebSocketServer\Sender`。
|
||||
|
||||
`Sender` 會判斷 `fd` 是否被當前 `Worker` 所持有,如果是,則會直接發送數據,如果不是,則會通過 `PipeMessage` 發送給除自己外的所有 `Worker`,然後由其他 `Worker` 進行判斷,
|
||||
如果是自己持有的 `fd`,就會發送對應數據到客户端。
|
||||
|
||||
`Sender` 支持 `push` 和 `disconnect` 兩個 `API`,如下:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
use Hyperf\HttpServer\Annotation\AutoController;
|
||||
use Hyperf\WebSocketServer\Sender;
|
||||
|
||||
/**
|
||||
* @AutoController
|
||||
*/
|
||||
class ServerController
|
||||
{
|
||||
/**
|
||||
* @Inject
|
||||
* @var Sender
|
||||
*/
|
||||
protected $sender;
|
||||
|
||||
public function close(int $fd)
|
||||
{
|
||||
go(function () use ($fd) {
|
||||
sleep(1);
|
||||
$this->sender->disconnect($fd);
|
||||
});
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
public function send(int $fd)
|
||||
{
|
||||
$this->sender->push($fd, 'Hello World.');
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
@ -100,7 +100,7 @@ class FooAspect extends AbstractAspect
|
||||
}
|
||||
```
|
||||
|
||||
> 注意目前的 AOP 機制尚未能直接切入 trait 的方法,您可通過使用類重寫該方法,並對使用類進行切入。
|
||||
> 2.0 版本已經可以支援切入 Trait,但要求 PHP 版本 >= 7.3。
|
||||
|
||||
## 代理類快取
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
## 如何提交我的元件?
|
||||
|
||||
如果您開發的協程元件適配了 Hyperf,那麼您可以直接對 [hyperf/hyperf](https://github.com/hyperf/hyperf) 專案的 `master` 分支發起您的 `Pull Request`,也就是更改當前頁`(./zh-cn/awesome-components.md)`。
|
||||
如果您開發的協程元件適配了 Hyperf,那麼您可以直接對 [hyperf/hyperf](https://github.com/hyperf/hyperf) 專案的 `master` 分支發起您的 `Pull Request`,也就是更改當前頁`(zh-cn/awesome-components.md)`。
|
||||
|
||||
## 如何適配 Hyperf ?
|
||||
|
||||
@ -34,6 +34,7 @@
|
||||
|
||||
- [hyperf/database](https://github.com/hyperf/database) Hyperf 官方提供的基於 Eloquent 衍生的資料庫 ORM,可複用於其它框架
|
||||
- [hyperf/model](https://github.com/hyperf/model) Hyperf 官方提供的基於 [hyperf/database](https://github.com/hyperf/database) 元件的自動模型快取元件
|
||||
- [reasno/fastmongo](https://github.com/Reasno/fastmongo) 基於 `hyperf/gotask` 實現的協程化 `MongoDB` 客戶端
|
||||
|
||||
## 依賴注入容器
|
||||
|
||||
@ -104,6 +105,7 @@
|
||||
- [mix-php/swoolefor](https://github.com/mix-php/swoolefor) 一個由 Mixphp 實現的通用熱更新元件
|
||||
- [buexplain/go-watch](https://github.com/buexplain/go-watch) 一個基於 Go 語言實現的通用熱更新元件
|
||||
- [remy/nodemon](https://github.com/remy/nodemon) 一個基於 node.js 實現的通用熱更新元件
|
||||
- [hyperf/watcher](zh-tw/watcher.md) 適配於 `Hyperf 2.0` 的熱更新元件
|
||||
|
||||
> Warning: 請勿於生產環境使用 `熱更新/熱過載` 功能
|
||||
|
||||
|
@ -1,11 +1,122 @@
|
||||
# 版本更新記錄
|
||||
|
||||
# v2.0.4 - 2020-07-27
|
||||
|
||||
## Added
|
||||
|
||||
- [#2144](https://github.com/hyperf/hyperf/pull/2144) 資料庫查詢事件 `Hyperf\Database\Events\QueryExecuted` 新增 `$result` 欄位。
|
||||
- [#2158](https://github.com/hyperf/hyperf/pull/2158) 路由 `Hyperf\HttpServer\Router\Handler` 中,新增 `$options` 欄位。
|
||||
- [#2162](https://github.com/hyperf/hyperf/pull/2162) 熱更新元件新增 `Hyperf\Watcher\Driver\FindDriver`。
|
||||
- [#2169](https://github.com/hyperf/hyperf/pull/2169) `Session` 元件新增配置 `session.options.domain`,用於替換 `Request` 中獲取的 `domain`。
|
||||
- [#2174](https://github.com/hyperf/hyperf/pull/2174) 模型生成器新增 `ModelRewriteTimestampsVisitor`,用於根據資料庫欄位 `created_at` 和 `updated_at`, 重寫模型欄位 `$timestamps`。
|
||||
- [#2175](https://github.com/hyperf/hyperf/pull/2175) 模型生成器新增 `ModelRewriteSoftDeletesVisitor`,用於根據資料庫欄位 `deleted_at`, 新增或者移除 `SoftDeletes`。
|
||||
- [#2176](https://github.com/hyperf/hyperf/pull/2176) 模型生成器新增 `ModelRewriteKeyInfoVisitor`,用於根據資料庫主鍵,重寫模型欄位 `$incrementing` `$primaryKey` 和 `$keyType`。
|
||||
|
||||
## Fixed
|
||||
|
||||
- [#2149](https://github.com/hyperf/hyperf/pull/2149) 修復自定義程序執行過程中無法從 Nacos 正常更新配置的 BUG。
|
||||
- [#2159](https://github.com/hyperf/hyperf/pull/2159) 修復使用 `gen:migration` 時,由於檔案已經存在導致的 `FATAL` 異常。
|
||||
|
||||
## Optimized
|
||||
|
||||
- [#2043](https://github.com/hyperf/hyperf/pull/2043) 當 `SCAN` 目錄都不存在時,丟擲更加友好的異常。
|
||||
- [#2182](https://github.com/hyperf/hyperf/pull/2182) 當使用 `WebSocket` 和 `Http` 服務且 `Http` 介面被訪問時,不會記錄 `WebSocket` 關閉連線的日誌。
|
||||
|
||||
# v2.0.3 - 2020-07-20
|
||||
|
||||
## 新增
|
||||
|
||||
- [#1554](https://github.com/hyperf/hyperf/pull/1554) 新增 `hyperf/nacos` 元件。
|
||||
- [#2082](https://github.com/hyperf/hyperf/pull/2082) 監聽器 `Hyperf\Signal\Handler\WorkerStopHandler` 新增訊號 `SIGINT` 監聽。
|
||||
- [#2097](https://github.com/hyperf/hyperf/pull/2097) `hyperf/filesystem` 新增 TencentCloud COS 支援.
|
||||
- [#2122](https://github.com/hyperf/hyperf/pull/2122) 新增 Trait `\Hyperf\Snowflake\Concern\HasSnowflake` 為模型自動生成雪花演算法的主鍵。
|
||||
|
||||
## 修復
|
||||
|
||||
- [#2017](https://github.com/hyperf/hyperf/pull/2017) 修復 Prometheus 使用 redis 打點時,改變 label 會導致收集報錯的 BUG。
|
||||
- [#2117](https://github.com/hyperf/hyperf/pull/2117) 修復使用 `server:watch` 時,註解 `@Inject` 有時會失效的 BUG。
|
||||
- [#2123](https://github.com/hyperf/hyperf/pull/2123) 修復 `tracer` 會記錄兩次 `Redis 指令` 的 BUG。
|
||||
- [#2139](https://github.com/hyperf/hyperf/pull/2139) 修復 `ValidationMiddleware` 在 `WebSocket` 服務下使用會報錯的 BUG。
|
||||
- [#2140](https://github.com/hyperf/hyperf/pull/2140) 修復請求丟擲異常時,`Session` 無法儲存的 BUG。
|
||||
|
||||
## 優化
|
||||
|
||||
- [#2080](https://github.com/hyperf/hyperf/pull/2080) 方法 `Hyperf\Database\Model\Builder::paginate` 中引數 `$perPage` 的型別從 `int` 更改為 `?int`。
|
||||
- [#2110](https://github.com/hyperf/hyperf/pull/2110) 在使用 `hyperf/watcher` 時,會先檢查程序是否存在,如果不存在,才會傳送 `SIGTERM` 訊號。
|
||||
- [#2116](https://github.com/hyperf/hyperf/pull/2116) 優化元件 `hyperf/di` 的依賴。
|
||||
- [#2121](https://github.com/hyperf/hyperf/pull/2121) 在使用 `gen:model` 時,如果使用者自定義了與資料庫欄位一致的欄位時,則會替換對應的 `@property`。
|
||||
- [#2129](https://github.com/hyperf/hyperf/pull/2129) 當 Response Json 格式化失敗時,會丟擲更加友好的錯誤提示。
|
||||
|
||||
# v2.0.2 - 2020-07-13
|
||||
|
||||
## 修復
|
||||
|
||||
- [#1898](https://github.com/hyperf/hyperf/pull/1898) 修復定時器規則 `$min-$max` 解析有誤的 BUG。
|
||||
- [#2037](https://github.com/hyperf/hyperf/pull/2037) 修復 TCP 服務,連線後共用一個協程,導致 DB 等連線池無法正常回收連線的 BUG。
|
||||
- [#2051](https://github.com/hyperf/hyperf/pull/2051) 修復 `CoroutineServer` 不會生成 `hyperf.pid` 的 BUG。
|
||||
- [#2055](https://github.com/hyperf/hyperf/pull/1695) 修復 `Guzzle` 在傳輸大資料包時會自動新增頭 `Expect: 100-Continue`,導致請求失敗的 BUG。
|
||||
- [#2059](https://github.com/hyperf/hyperf/pull/2059) 修復 `SocketIOServer` 中 `Redis` 重連失敗的 BUG。
|
||||
- [#2067](https://github.com/hyperf/hyperf/pull/2067) 修復 `hyperf/watcher` 元件 `Syntax` 錯誤會導致程序異常。
|
||||
- [#2085](https://github.com/hyperf/hyperf/pull/2085) 修復註解 `RetryFalsy` 會導致獲得正確的結果後,再次重試。
|
||||
- [#2089](https://github.com/hyperf/hyperf/pull/2089) 修復使用 `gen:command` 後,指令碼必須要進行修改,才能被載入到的 BUG。
|
||||
- [#2093](https://github.com/hyperf/hyperf/pull/2093) 修復指令碼 `vendor:publish` 沒有返回碼導致報錯的 BUG。
|
||||
|
||||
## 新增
|
||||
|
||||
- [#1860](https://github.com/hyperf/hyperf/pull/1860) 為 `Server` 新增預設的 `OnWorkerExit` 回撥。
|
||||
- [#2042](https://github.com/hyperf/hyperf/pull/2042) 為熱更新元件,新增檔案掃描驅動。
|
||||
- [#2054](https://github.com/hyperf/hyperf/pull/2054) 為模型快取新增 `Eager Load` 功能。
|
||||
|
||||
## 優化
|
||||
|
||||
- [#2049](https://github.com/hyperf/hyperf/pull/2049) 優化熱更新元件的 Stdout 輸出。
|
||||
- [#2090](https://github.com/hyperf/hyperf/pull/2090) 為 `hyperf/session` 元件適配非 `Hyperf` 的 `Response`。
|
||||
|
||||
## 變更
|
||||
|
||||
- [#2031](https://github.com/hyperf/hyperf/pull/2031) 常量元件的錯誤碼只支援 `int` 和 `string`。
|
||||
- [#2065](https://github.com/hyperf/hyperf/pull/2065) `WebSocket` 訊息傳送器 `Hyperf\WebSocketServer\Sender` 支援 `push` 和 `disconnect`。
|
||||
- [#2100](https://github.com/hyperf/hyperf/pull/2100) 元件 `hyperf/utils` 更新依賴 `doctrine/inflector` 版本到 `^2.0`。
|
||||
|
||||
## 移除
|
||||
|
||||
- [#2065](https://github.com/hyperf/hyperf/pull/2065) 移除 `Hyperf\WebSocketServer\Sender` 對方法 `send` `sendto` 和 `close` 的支援,請使用 `push` 和 `disconnect`。
|
||||
|
||||
# v2.0.1 - 2020-07-02
|
||||
|
||||
## 新增
|
||||
|
||||
- [#1934](https://github.com/hyperf/hyperf/pull/1934) 增加指令碼 `gen:constant` 用於建立常量類。
|
||||
- [#1982](https://github.com/hyperf/hyperf/pull/1982) 新增熱更新元件,檔案修改後自動收集註解,自動重啟。
|
||||
|
||||
## 修復
|
||||
|
||||
- [#1952](https://github.com/hyperf/hyperf/pull/1952) 修復資料庫遷移類存在時,也會生成同類名類,導致類名衝突的 BUG。
|
||||
- [#1960](https://github.com/hyperf/hyperf/pull/1960) 修復 `Hyperf\HttpServer\ResponseEmitter::isMethodsExists()` 判斷錯誤的 BUG。
|
||||
- [#1961](https://github.com/hyperf/hyperf/pull/1961) 修復因檔案 `config/autoload/aspects.php` 不存在導致服務無法啟動的 BUG。
|
||||
- [#1964](https://github.com/hyperf/hyperf/pull/1964) 修復介面請求時,資料體為空會導致 `500` 錯誤的 BUG。
|
||||
- [#1965](https://github.com/hyperf/hyperf/pull/1965) 修復 `initRequestAndResponse` 失敗後,會導致請求狀態碼與實際不符的 BUG。
|
||||
- [#1968](https://github.com/hyperf/hyperf/pull/1968) 修復當修改 `aspects.php` 檔案後,`Aspect` 無法安裝修改後的結果執行的 BUG。
|
||||
- [#1985](https://github.com/hyperf/hyperf/pull/1985) 修復註解全域性配置不全為小寫時,會導致 `global_imports` 失敗的 BUG。
|
||||
- [#1990](https://github.com/hyperf/hyperf/pull/1990) 修復當父類存在與子類一樣的成員變數時, `@Inject` 無法正常使用的 BUG。
|
||||
- [#2019](https://github.com/hyperf/hyperf/pull/2019) 修復指令碼 `gen:model` 因為使用了 `morphTo` 或 `where` 導致生成對應的 `@property` 失敗的 BUG。
|
||||
- [#2026](https://github.com/hyperf/hyperf/pull/2026) 修復當使用了魔術方法時,LazyLoad 代理生成有誤的 BUG。
|
||||
|
||||
## 變更
|
||||
|
||||
- [#1986](https://github.com/hyperf/hyperf/pull/1986) 當沒有設定正確的 `swoole.use_shortname` 變更指令碼 `exit_code` 為 `SIGTERM`。
|
||||
|
||||
## 優化
|
||||
|
||||
- [#1959](https://github.com/hyperf/hyperf/pull/1959) 優化類 `ClassLoader` 可以更容易被使用者繼承並修改。
|
||||
- [#2002](https://github.com/hyperf/hyperf/pull/2002) 當 `PHP` 版本大於等於 `7.3` 時,支援 `AOP` 切入 `Trait`。
|
||||
|
||||
# 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 功能的類;
|
||||
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 版本,都可以生效了;
|
||||
@ -274,7 +385,7 @@ return [
|
||||
|
||||
## 修復
|
||||
|
||||
- [#1445](https://github.com/hyperf/hyperf/pull/1445) 修復命令 `describe:route` 缺失了帶引數的路由;
|
||||
- [#1445](https://github.com/hyperf/hyperf/pull/1445) 修復命令 `describe:routes` 缺失了帶引數的路由;
|
||||
- [#1449](https://github.com/hyperf/hyperf/pull/1449) 修復了高基數請求路徑的記憶體溢位的問題;
|
||||
- [#1454](https://github.com/hyperf/hyperf/pull/1454) 修復 Collection 的 `flatten()` 方法因為 `INF` 引數值為 `float` 型別導致無法使用的問題;
|
||||
- [#1458](https://github.com/hyperf/hyperf/pull/1458) 修復了 Guzzle 不支援 Elasticsearch 版本大於 7.0 的問題;
|
||||
|
@ -13,7 +13,7 @@ composer require hyperf/circuit-breaker
|
||||
## 使用熔斷器
|
||||
|
||||
熔斷器的使用十分簡單,只需要加入 `Hyperf\CircuitBreaker\Annotation\CircuitBreaker` 註解,就可以根據規定策略,進行熔斷。
|
||||
比如我們需要到另外服務中查詢使用者列表,使用者列表需要關聯很多的表,查詢效率較低,但平常併發量不高的時候,相應速度還說得過去。一旦併發量激增,就會導致響應速度變慢,並會使對方服務出現慢查。這個時候,我們只需要配置一下熔斷超時時間 `timeout` 為 0.05 秒,失敗計數 `failCounter` 超過 1 次後熔斷,相應 `fallback` 為 `App\Service\UserService` 類的 `searchFallback` 方法。這樣當響應超時並觸發熔斷後,就不會再請求對端的服務了,而是直接將服務降級從當前專案中返回資料,即根據 `fallback` 指定的方法來進行返回。
|
||||
比如我們需要到另外服務中查詢使用者列表,使用者列表需要關聯很多的表,查詢效率較低,但平常併發量不高的時候,響應速度還說得過去。一旦併發量激增,就會導致響應速度變慢,並會使對方服務出現慢查。這個時候,我們只需要配置一下熔斷超時時間 `timeout` 為 0.05 秒,失敗計數 `failCounter` 超過 1 次後熔斷,相應 `fallback` 為 `App\Service\UserService` 類的 `searchFallback` 方法。這樣當響應超時並觸發熔斷後,就不會再請求對端的服務了,而是直接將服務降級從當前專案中返回資料,即根據 `fallback` 指定的方法來進行返回。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
@ -360,4 +360,80 @@ array(2) {
|
||||
|
||||
```
|
||||
|
||||
# 執行命令
|
||||
|
||||
## 命令列中執行
|
||||
|
||||
```bash
|
||||
php bin/hyperf.php foo
|
||||
```
|
||||
|
||||
## 在 Command 中執行其他命令
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use Hyperf\Command\Command as HyperfCommand;
|
||||
use Hyperf\Command\Annotation\Command;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
* @Command
|
||||
*/
|
||||
class FooCommand extends HyperfCommand
|
||||
{
|
||||
/**
|
||||
* @var ContainerInterface
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
|
||||
parent::__construct('foo');
|
||||
}
|
||||
|
||||
public function configure()
|
||||
{
|
||||
parent::configure();
|
||||
$this->setDescription('foo command');
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$this->call('bar', [
|
||||
'--foo' => 'foo'
|
||||
]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 在非 Command 中執行命令
|
||||
|
||||
```php
|
||||
$command = 'foo';
|
||||
|
||||
$params = ["command" => $command, "--foo" => "foo", "--bar" => "bar"];
|
||||
|
||||
// 可以根據自己的需求, 選擇使用的 input/output
|
||||
$input = new ArrayInput($params);
|
||||
$output = new NullOutput();
|
||||
|
||||
/** @var \Psr\Container\ContainerInterface $container */
|
||||
$container = \Hyperf\Utils\ApplicationContext::getContainer();
|
||||
|
||||
/** @var \Symfony\Component\Console\Application $application */
|
||||
$application = $container->get(\Hyperf\Contract\ApplicationInterface::class);
|
||||
$application->setAutoExit(false);
|
||||
|
||||
// 這種方式: 不會暴露出命令執行中的異常, 不會阻止程式返回
|
||||
$exitCode = $application->run($input, $output);
|
||||
|
||||
// 第二種方式: 會暴露異常, 需要自己捕捉和處理執行中的異常, 否則會阻止程式的返回
|
||||
$exitCode = $application->find($command)->run($input, $output);
|
||||
```
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
Hyperf 為您提供了分散式系統的外部化配置支援,預設適配了:
|
||||
|
||||
- 由攜程開源的 [ctripcorp/apollo](https://github.com/ctripcorp/apollo),由 [hyper/config-apollo](https://github.com/hyperf/config-apollo) 元件提供功能支援。
|
||||
- 阿里雲提供的免費配置中心服務 [應用配置管理(ACM, Application Config Manager)](https://help.aliyun.com/product/59604.html),由 [hyper/config-aliyun-acm](https://github.com/hyperf/config-aliyun-acm) 元件提供功能支援。
|
||||
- 由攜程開源的 [ctripcorp/apollo](https://github.com/ctripcorp/apollo),由 [hyperf/config-apollo](https://github.com/hyperf/config-apollo) 元件提供功能支援。
|
||||
- 阿里雲提供的免費配置中心服務 [應用配置管理(ACM, Application Config Manager)](https://help.aliyun.com/product/59604.html),由 [hyperf/config-aliyun-acm](https://github.com/hyperf/config-aliyun-acm) 元件提供功能支援。
|
||||
|
||||
## 為什麼要使用配置中心?
|
||||
|
||||
|
@ -23,6 +23,7 @@ config
|
||||
│ ├── commands.php // 用於管理自定義命令
|
||||
│ ├── consul.php // 用於管理 Consul 客戶端
|
||||
│ ├── databases.php // 用於管理資料庫客戶端
|
||||
│ ├── dependencies.php // 用於管理 DI 的依賴關係和類對應關係
|
||||
│ ├── devtool.php // 用於管理開發者工具
|
||||
│ ├── exceptions.php // 用於管理異常處理器
|
||||
│ ├── listeners.php // 用於管理事件監聽者
|
||||
@ -34,7 +35,6 @@ config
|
||||
│ └── server.php // 用於管理 Server 服務
|
||||
├── config.php // 用於管理使用者或框架的配置,如配置相對獨立亦可放於 autoload 資料夾內
|
||||
├── container.php // 負責容器的初始化,作為一個配置檔案執行並最終返回一個 Psr\Container\ContainerInterface 物件
|
||||
├── dependencies.php // 用於管理 DI 的依賴關係和類對應關係
|
||||
└── routes.php // 用於管理路由
|
||||
```
|
||||
|
||||
|
@ -20,7 +20,7 @@ $message = ErrorCode::messages[ErrorCode::SERVER_ERROR] ?? '未知錯誤';
|
||||
|
||||
```
|
||||
|
||||
但這種實現方式並不友好,每當要查詢錯誤碼與對應錯誤資訊時,都要在當前 `Class` 中搜索兩次。所以框架提供了基於註解的列舉類。
|
||||
但這種實現方式並不友好,每當要查詢錯誤碼與對應錯誤資訊時,都要在當前 `Class` 中搜索兩次,所以框架提供了基於註解的列舉類。
|
||||
|
||||
## 安裝
|
||||
|
||||
@ -32,6 +32,14 @@ composer require hyperf/constants
|
||||
|
||||
### 定義列舉類
|
||||
|
||||
通過 `gen:constant` 命令可以快速的生成一個列舉類。
|
||||
|
||||
```bash
|
||||
php bin/hyperf.php gen:constant ErrorCode
|
||||
```
|
||||
|
||||
!> 此生成命令僅在 [hyperf/constants](https://github.com/hyperf/constants) 元件版本大於等於 v2.0.1 版本時可用,小於此版本時請手動建立列舉類。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
@ -57,7 +65,6 @@ class ErrorCode extends AbstractConstants
|
||||
*/
|
||||
const SYSTEM_INVALID = 700;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
使用者可以使用 `ErrorCode::getMessage(ErrorCode::SERVER_ERROR)` 來獲取對應錯誤資訊。
|
||||
@ -88,7 +95,6 @@ class BusinessException extends ServerException
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### 丟擲異常
|
||||
@ -112,7 +118,6 @@ class IndexController extends Controller
|
||||
throw new BusinessException(ErrorCode::SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### 可變引數
|
||||
@ -139,7 +144,6 @@ class ErrorCode extends AbstractConstants
|
||||
$message = ErrorCode::getMessage(ErrorCode::PARAMS_INVALID, ['user_id']);
|
||||
|
||||
// 1.2 版本以下 可以使用以下方式,但會在 1.2 版本移除
|
||||
|
||||
$message = ErrorCode::getMessage(ErrorCode::PARAMS_INVALID, 'user_id');
|
||||
```
|
||||
|
||||
@ -153,7 +157,7 @@ $message = ErrorCode::getMessage(ErrorCode::PARAMS_INVALID, 'user_id');
|
||||
composer require hyperf/translation
|
||||
```
|
||||
|
||||
相關配置詳見 [國際化](translation.md)
|
||||
相關配置詳見 [國際化](zh-tw/translation.md)
|
||||
|
||||
```php
|
||||
<?php
|
||||
@ -180,4 +184,3 @@ class ErrorCode extends AbstractConstants
|
||||
|
||||
$message = ErrorCode::getMessage(ErrorCode::SERVER_ERROR, ['param' => 'user_id']);
|
||||
```
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
Hyperf 是一個開源專案,一個開源專案的發展離不開開源社群的力量支援,如果您希望參與 Hyperf 的開發,可以先從 [issues](https://github.com/hyperf/hyperf/issues?page=2&q=is%3Aissue+is%3Aopen) 開始,通常來說會有以下的一些步驟:
|
||||
|
||||
1. 關注 [issues](https://github.com/hyperf/hyperf/issues?page=2&q=is%3Aissue+is%3Aopen) 的動態,評論回覆幫助提出疑問的使用者;
|
||||
2. 根據 [issues](https://github.com/hyperf/hyperf/issues?page=2&q=is%3Aissue+is%3Aopen) 的內容,找尋根據自己當前對 Hyperf 的瞭解程度,去修復力所能及的 BUG 或實現功能,並以 [Pull Request](https://https://github.com/hyperf/pulls) 的形式提交至 [hyperf/hyperf](https://github.com/hyperf/hyperf) 倉庫;
|
||||
2. 根據 [issues](https://github.com/hyperf/hyperf/issues?page=2&q=is%3Aissue+is%3Aopen) 的內容,找尋根據自己當前對 Hyperf 的瞭解程度,去修復力所能及的 BUG 或實現功能,並以 [Pull Request](https://github.com/hyperf/hyperf/pulls) 的形式提交至 [hyperf/hyperf](https://github.com/hyperf/hyperf) 倉庫;
|
||||
3. 關注自己提交 Pull Request 的進度和狀態,以推動您的 Pull Request 儘快合入主倉庫;
|
||||
4. 對其他人提交的 Pull Request 進行 Code Review,並給出您的建議和看法。
|
||||
5. 根據他人或自己的需求,研發獨立的功能元件;
|
||||
|
137
docs/zh-tw/db/gen.md
Normal file
137
docs/zh-tw/db/gen.md
Normal file
@ -0,0 +1,137 @@
|
||||
# 模型建立指令碼
|
||||
|
||||
Hyperf 提供了建立模型的命令,您可以很方便的根據資料表建立對應模型。命令通過 `AST` 生成模型,所以當您增加了某些方法後,也可以使用指令碼方便的重置模型。
|
||||
|
||||
```bash
|
||||
php bin/hyperf.php gen:model table_name
|
||||
```
|
||||
|
||||
## 建立模型
|
||||
|
||||
可選引數如下:
|
||||
|
||||
| 引數 | 型別 | 預設值 | 備註 |
|
||||
| :----------------: | :----: | :-------------------------------: | :-----------------------------------------------: |
|
||||
| --pool | string | `default` | 連線池,指令碼會根據當前連線池配置建立 |
|
||||
| --path | string | `app/Model` | 模型路徑 |
|
||||
| --force-casts | bool | `false` | 是否強制重置 `casts` 引數 |
|
||||
| --prefix | string | 空字串 | 表字首 |
|
||||
| --inheritance | string | `Model` | 父類 |
|
||||
| --uses | string | `Hyperf\DbConnection\Model\Model` | 配合 `inheritance` 使用 |
|
||||
| --refresh-fillable | bool | `false` | 是否重新整理 `fillable` 引數 |
|
||||
| --table-mapping | array | `[]` | 為表名 -> 模型增加對映關係 比如 ['users:Account'] |
|
||||
| --ignore-tables | array | `[]` | 不需要生成模型的表名 比如 ['users'] |
|
||||
| --with-comments | bool | `false` | 是否增加欄位註釋 |
|
||||
| --property-case | int | `0` | 欄位型別 0 蛇形 1 駝峰 |
|
||||
|
||||
當使用 `--property-case` 將欄位型別轉化為駝峰時,還需要手動在模型中加入 `Hyperf\Database\Model\Concerns\CamelCase`。
|
||||
|
||||
對應配置也可以配置到 `databases.{pool}.commands.gen:model` 中,如下
|
||||
|
||||
> 中劃線都需要轉化為下劃線
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Hyperf\Database\Commands\ModelOption;
|
||||
|
||||
return [
|
||||
'default' => [
|
||||
// 忽略其他配置
|
||||
'commands' => [
|
||||
'gen:model' => [
|
||||
'path' => 'app/Model',
|
||||
'force_casts' => true,
|
||||
'inheritance' => 'Model',
|
||||
'uses' => '',
|
||||
'refresh_fillable' => true,
|
||||
'table_mapping' => [],
|
||||
'with_comments' => true,
|
||||
'property_case' => ModelOption::PROPERTY_SNAKE_CASE,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
```
|
||||
|
||||
建立的模型如下
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Model;
|
||||
|
||||
use Hyperf\DbConnection\Model\Model;
|
||||
|
||||
/**
|
||||
* @property $id
|
||||
* @property $name
|
||||
* @property $gender
|
||||
* @property $created_at
|
||||
* @property $updated_at
|
||||
*/
|
||||
class User extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'user';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = ['id', 'name', 'gender', 'created_at', 'updated_at'];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = ['id' => 'integer', 'gender' => 'integer'];
|
||||
}
|
||||
```
|
||||
|
||||
## Visitors
|
||||
|
||||
框架提供了幾個 `Visitors`,方便使用者對指令碼能力進行擴充套件。使用方法很簡單,只需要在 `visitors` 配置中,新增對應的 `Visitor` 即可。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
'default' => [
|
||||
// 忽略其他配置
|
||||
'commands' => [
|
||||
'gen:model' => [
|
||||
'visitors' => [
|
||||
Hyperf\Database\Commands\Ast\ModelRewriteKeyInfoVisitor::class
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
```
|
||||
|
||||
### 可選 Visitors
|
||||
|
||||
- Hyperf\Database\Commands\Ast\ModelRewriteKeyInfoVisitor
|
||||
|
||||
此 `Visitor` 可以根據資料庫中主鍵,生成對應的 `$incrementing` `$primaryKey` 和 `$keyType`。
|
||||
|
||||
- Hyperf\Database\Commands\Ast\ModelRewriteSoftDeletesVisitor
|
||||
|
||||
此 `Visitor` 可以根據 `DELETED_AT` 常量判斷該模型是否含有軟刪除欄位,如果存在,則新增對應的 Trait `SoftDeletes`。
|
||||
|
||||
- Hyperf\Database\Commands\Ast\ModelRewriteTimestampsVisitor
|
||||
|
||||
此 `Visitor` 可以根據 `created_at` 和 `updated_at` 自動判斷,是否啟用預設記錄 `建立和修改時間` 的功能。
|
@ -146,3 +146,47 @@ User::query(true)->where('gender', '>', 1)->delete();
|
||||
當生產環境使用了模型快取時,如果已經建立了對應快取資料,但此時又因為邏輯變更,添加了新的欄位,並且預設值不是 `0`、`空字元`、`null` 這類資料時,就會導致在資料查詢時,從快取中查出來的資料與資料庫中的資料不一致。
|
||||
|
||||
對於這種情況,我們可以修改 `use_default_value` 為 `true`,並新增 `Hyperf\DbConnection\Listener\InitTableCollectorListener` 到 `listener.php` 配置中,使 Hyperf 應用在啟動時主動去獲取資料庫的欄位資訊,並在獲取快取資料時與之比較並進行快取資料修正。
|
||||
|
||||
### EagerLoad
|
||||
|
||||
當我們使用模型關係時,可以通過 `load` 解決 `N+1` 的問題,但仍然需要查一次資料庫。模型快取通過重寫了 `ModelBuilder`,可以讓使用者儘可能的從快取中拿到對應的模型。
|
||||
|
||||
> 本功能不支援 `morphTo` 和不是隻有 `whereIn` 查詢的關係模型。
|
||||
|
||||
以下提供兩種方式:
|
||||
|
||||
1. 配置 EagerLoadListener,直接使用 `loadCache` 方法。
|
||||
|
||||
修改 `listeners.php` 配置
|
||||
|
||||
```php
|
||||
return [
|
||||
Hyperf\ModelCache\Listener\EagerLoadListener::class,
|
||||
];
|
||||
```
|
||||
|
||||
通過 `loadCache` 方法,載入對應的模型關係。
|
||||
|
||||
```php
|
||||
$books = Book::findManyFromCache([1,2,3]);
|
||||
$books->loadCache(['user']);
|
||||
|
||||
foreach ($books as $book){
|
||||
var_dump($book->user);
|
||||
}
|
||||
```
|
||||
|
||||
2. 使用 EagerLoader
|
||||
|
||||
```php
|
||||
use Hyperf\ModelCache\EagerLoad\EagerLoader;
|
||||
use Hyperf\Utils\ApplicationContext;
|
||||
|
||||
$books = Book::findManyFromCache([1,2,3]);
|
||||
$loader = ApplicationContext::getContainer()->get(EagerLoader::class);
|
||||
$loader->load($books, ['user']);
|
||||
|
||||
foreach ($books as $book){
|
||||
var_dump($book->user);
|
||||
}
|
||||
```
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user