mirror of
https://gitee.com/hyperf/hyperf.git
synced 2024-11-30 02:37:58 +08:00
Merge branch '2.2' into 3.0-merge2
# Conflicts: # docs/en/component-guide/configprovider.md # docs/en/component-guide/create.md # docs/en/component-guide/intro.md # docs/en/db/model.md # docs/en/release-planning.md # docs/zh-cn/db/model.md # docs/zh-cn/release-planning.md # docs/zh-hk/db/model.md # docs/zh-hk/release-planning.md # docs/zh-tw/db/model.md # docs/zh-tw/release-planning.md
This commit is contained in:
commit
e2b188bc4c
@ -1,16 +1,16 @@
|
||||
# ConfigProvider mechanism
|
||||
# ConfigProvider 机制
|
||||
|
||||
The ConfigProvider mechanism is a very important mechanism for Hyperf componentization. `Decoupling between components` and `component independence` and `component reusability` are all based on this mechanism.
|
||||
ConfigProvider 机制对于 Hyperf 组件化来说是个非常重要的机制,`组件间的解耦` 和 `组件的独立性` 以及 `组件的可重用性` 都是基于这个机制才得以实现。
|
||||
|
||||
# What is the ConfigProvider mechanism?
|
||||
# 什么是 ConfigProvider 机制 ?
|
||||
|
||||
In short, each component will provide a `ConfigProvider`, usually a `ConfigProvider` class is provided in the root directory of the component, and `ConfigProvider` will provide all the configuration information of the corresponding component, which will be started by the Hyperf framework When loading, the configuration information in `ConfigProvider` will be merged into the corresponding implementation class of `Hyperf\Contract\ConfigInterface`, so as to realize the configuration initialization when each component is used under the Hyperf framework.
|
||||
简单来说,就是每个组件都会提供一个 `ConfigProvider`,通常是在组件的根目录提供一个 `ConfigProvider` 的类,`ConfigProvider` 会提供对应组件的所有配置信息,这些信息都会被 Hyperf 框架在启动时加载,最终`ConfigProvider` 内的配置信息会被合并到 `Hyperf\Contract\ConfigInterface` 对应的实现类去,从而实现各个组件在 Hyperf 框架下使用时要进行的配置初始化。
|
||||
|
||||
`ConfigProvider` itself does not have any dependencies, does not inherit any abstract classes and does not require to implement any interfaces, just provide a `__invoke` method and return an array of corresponding configuration structures.
|
||||
`ConfigProvider` 本身不具备任何依赖,不继承任何的抽象类和不要求实现任何的接口,只需提供一个 `__invoke` 方法并返回一个对应配置结构的数组即可。
|
||||
|
||||
# How to define a ConfigProvider?
|
||||
# 如何定义一个 ConfigProvider ?
|
||||
|
||||
Usually, `ConfigProvider` is defined in the root directory of the component. A `ConfigProvider` class is usually as follows:
|
||||
通常来说,`ConfigProvider` 会定义在组件的根目录下,一个 `ConfigProvider` 类通常如下:
|
||||
|
||||
```php
|
||||
<?php
|
||||
@ -22,9 +22,9 @@ class ConfigProvider
|
||||
public function __invoke(): array
|
||||
{
|
||||
return [
|
||||
// Merged into config/autoload/dependencies.php file
|
||||
// 合并到 config/autoload/dependencies.php 文件
|
||||
'dependencies' => [],
|
||||
// Merged into config/autoload/annotations.php file
|
||||
// 合并到 config/autoload/annotations.php 文件
|
||||
'annotations' => [
|
||||
'scan' => [
|
||||
'paths' => [
|
||||
@ -32,40 +32,40 @@ class ConfigProvider
|
||||
],
|
||||
],
|
||||
],
|
||||
// The definition of the default Command is merged into Hyperf\Contract\ConfigInterface and understood in another way, that is, it corresponds to config/autoload/commands.php
|
||||
// 默认 Command 的定义,合并到 Hyperf\Contract\ConfigInterface 内,换个方式理解也就是与 config/autoload/commands.php 对应
|
||||
'commands' => [],
|
||||
// similar to commands
|
||||
// 与 commands 类似
|
||||
'listeners' => [],
|
||||
// The default configuration file of the component, that is, after executing the command, the corresponding file of source will be copied to the file corresponding to destination
|
||||
// 组件默认配置文件,即执行命令后会把 source 的对应的文件复制为 destination 对应的的文件
|
||||
'publish' => [
|
||||
[
|
||||
'id' => 'config',
|
||||
'description' => 'description of this config file.', // describe
|
||||
// It is recommended that the default configuration be placed in the publish folder with the same file name as the component name
|
||||
'source' => __DIR__ . '/../publish/file.php', // Corresponding configuration file path
|
||||
'destination' => BASE_PATH . '/config/autoload/file.php', // Copy as the file under this path
|
||||
'description' => 'description of this config file.', // 描述
|
||||
// 建议默认配置放在 publish 文件夹中,文件命名和组件名称相同
|
||||
'source' => __DIR__ . '/../publish/file.php', // 对应的配置文件路径
|
||||
'destination' => BASE_PATH . '/config/autoload/file.php', // 复制为这个路径下的该文件
|
||||
],
|
||||
],
|
||||
// You can also continue to define other configurations, which will eventually be merged into the configuration store corresponding to the ConfigInterface
|
||||
// 亦可继续定义其它配置,最终都会合并到与 ConfigInterface 对应的配置储存器中
|
||||
];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Default Profile Description
|
||||
## 默认配置文件说明
|
||||
|
||||
After defining `publish` in `ConfigProvider`, you can use the following commands to quickly generate configuration files
|
||||
在 `ConfigProvider` 中定义好 `publish` 后,可以使用如下命令快速生成配置文件
|
||||
|
||||
```bash
|
||||
php bin/hyperf.php vendor:publish 包名称
|
||||
```
|
||||
|
||||
If the package name is `hyperf/amqp`, you can execute the command to generate the `amqp` default configuration file
|
||||
如包名称为 `hyperf/amqp`,可执行命令来生成 `amqp` 默认的配置文件
|
||||
```bash
|
||||
php bin/hyperf.php vendor:publish hyperf/amqp
|
||||
```
|
||||
|
||||
Just creating a class will not be loaded automatically by Hyperf, you still need to add some definitions to the component's `composer.json` to tell Hyperf that this is a ConfigProvider class that needs to be loaded, you need to add some definitions in the component's `composer.json` Add the `extra.hyperf.config` configuration to the file, and specify the corresponding namespace of the `ConfigProvider` class, as follows:
|
||||
只创建一个类并不会被 Hyperf 自动的加载,您仍需在组件的 `composer.json` 添加一些定义,告诉 Hyperf 这是一个 ConfigProvider 类需要被加载,您需要在组件内的 `composer.json` 文件内增加 `extra.hyperf.config` 配置,并指定对应的 `ConfigProvider` 类的命名空间,如下所示:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -86,19 +86,19 @@ Just creating a class will not be loaded automatically by Hyperf, you still need
|
||||
}
|
||||
```
|
||||
|
||||
After the definition, you need to execute `composer install` or `composer update` or `composer dump-autoload` and other commands that will make Composer regenerate the `composer.lock` file before it can be read normally.
|
||||
定义了之后需执行 `composer install` 或 `composer update` 或 `composer dump-autoload` 等会让 Composer 重新生成 `composer.lock` 文件的命令,才能被正常读取。
|
||||
|
||||
# Execution process of the ConfigProvider mechanism
|
||||
# ConfigProvider 机制的执行流程
|
||||
|
||||
The configuration of `ConfigProvider` is not necessarily divided in this way. This is some conventional format. In fact, the final decision on how to parse these configurations is also up to the user. The user can modify the Skeleton project's `config/container.php' ` code in the file to adjust the relevant loading, which means that the `config/container.php` file determines the scanning and loading of the `ConfigProvider`.
|
||||
关于 `ConfigProvider` 的配置并非一定就是这样去划分,这是一些约定成俗的格式,实际上最终如何来解析这些配置的决定权也在于用户,用户可通过修改 Skeleton 项目的 `config/container.php` 文件内的代码来调整相关的加载,也就意味着,`config/container.php` 文件决定了 `ConfigProvider` 的扫描和加载。
|
||||
|
||||
# Component design specification
|
||||
# 组件设计规范
|
||||
|
||||
Since the `extra` property in `composer.json` has no other function and influence when the data is not used, the definitions in these components will not cause any interference and influence when other frameworks are used, so `ConfigProvider` is A mechanism that only acts on the Hyperf framework and will not have any impact on other frameworks that do not use this mechanism, which lays the foundation for the reuse of components, but it also requires the following when designing components. specification:
|
||||
由于 `composer.json` 内的 `extra` 属性在数据不被利用时无其它作用和影响,故这些组件内的定义在其它框架使用时,不会造成任何的干扰和影响,故`ConfigProvider` 是一种仅作用于 Hyperf 框架的机制,对其它没有利用此机制的框架不会造成任何的影响,这也就为组件的复用打下了基础,但这也要求在进行组件设计时,必须遵循以下规范:
|
||||
|
||||
- All classes must be designed to allow use through standard `OOP` usage, all Hyperf-specific functionality must be provided as enhancements and provided as separate classes, which means that standard non-Hyperf frameworks can still pass the standard means to achieve the use of components;
|
||||
- If the dependent design of a component can meet the [PSR standard](https://www.php-fig.org/psr), it will first satisfy and depend on the corresponding interface rather than the implementation class; such as [PSR standard](https://www.php-fig.org/psr) www.php-fig.org/psr) does not contain functions, it can satisfy the interface in the contract library [Hyperf/contract](https://github.com/hyperf/contract) defined by Hyperf first and depend on The corresponding interface instead of the implementing class;
|
||||
- For the enhanced function classes that implement Hyperf's proprietary functions, usually also have dependencies on some components of Hyperf, so the dependencies of these components should not be written in the `require` item of `composer.json`, but write exists as a suggestion in the `suggest` item;
|
||||
- Component design should not perform any dependency injection through annotations. The injection method should only use the `constructor injection` method, which can also meet the use under `OOP`;
|
||||
- During component design, any function definition should not be carried out through annotations, and function definitions should only be defined through `ConfigProvider`;
|
||||
- The class design should not store state data as much as possible, because this will cause the class to not be provided as an object with a long life cycle, and it will not be able to use the dependency injection function very conveniently, which will reduce performance and state to a certain extent. Data should be stored through the `Hyperf\Context\Context` coroutine context;
|
||||
- 所有类的设计都必须允许通过标准 `OOP` 的使用方式来使用,所有 Hyperf 专有的功能必须作为增强功能并以单独的类来提供,也就意味着在非 Hyperf 框架下仍能通过标准的手段来实现组件的使用;
|
||||
- 组件的依赖设计如果可满足 [PSR 标准](https://www.php-fig.org/psr) 则优先满足且依赖对应的接口而不是实现类;如 [PSR 标准](https://www.php-fig.org/psr) 没有包含的功能,则可满足由 Hyperf 定义的契约库 [Hyperf/contract](https://github.com/hyperf/contract) 内的接口时优先满足且依赖对应的接口而不是实现类;
|
||||
- 对于实现 Hyperf 专有功能所增加的增强功能类,通常来说也会对 Hyperf 的一些组件有依赖,那么这些组件的依赖不应该写在 `composer.json` 的 `require` 项,而是写在 `suggest` 项作为建议项存在;
|
||||
- 组件设计时不应该通过注解进行任何的依赖注入,注入方式应只使用 `构造函数注入` 的方式,这样同时也能满足在 `OOP` 下的使用;
|
||||
- 组件设计时不应该通过注解进行任何的功能定义,功能定义应只通过 `ConfigProvider` 来定义;
|
||||
- 类的设计时应尽可能的不储存状态数据,因为这会导致这个类不能作为长生命周期的对象来提供,也无法很方便的使用依赖注入功能,这样会在一定程度下降低性能,状态数据应都通过 `Hyperf\Utils\Context` 协程上下文来储存;
|
||||
|
@ -1,29 +1,29 @@
|
||||
# Create new component
|
||||
# 创建新的组件
|
||||
|
||||
`Hyperf` Official tools are provided to quickly create component packages.
|
||||
`Hyperf` 官方提供了工具来快速创建组件包。
|
||||
|
||||
```
|
||||
# Create a component package adapted to the latest version of Hyperf
|
||||
# 创建适配 Hyperf 最新版本的组件包
|
||||
composer create-project hyperf/component-creator your_component dev-master
|
||||
|
||||
# Create a package for Hyperf 3.0
|
||||
composer create-project hyperf/component-creator your_component "3.0.*"
|
||||
# 创建适配 Hyperf 2.0 版本的组件包
|
||||
composer create-project hyperf/component-creator your_component "2.0.*"
|
||||
```
|
||||
|
||||
## Using an unpublished component package in a project
|
||||
## 在项目中使用未发布的组件包
|
||||
|
||||
Suppose the project directory is as follows
|
||||
假设项目目录如下
|
||||
|
||||
```
|
||||
/opt/project // project directory
|
||||
/opt/your_component // Component package directory
|
||||
/opt/project // 项目目录
|
||||
/opt/your_component // 组件包目录
|
||||
```
|
||||
|
||||
Suppose the component is named `your_component/your_component`
|
||||
假设组件名为 `your_component/your_component`
|
||||
|
||||
Revise /opt/project/composer.json
|
||||
修改 /opt/project/composer.json
|
||||
|
||||
> Other irrelevant configurations are omitted below
|
||||
> 以下省略其他不相干的配置
|
||||
|
||||
```json
|
||||
{
|
||||
@ -39,4 +39,11 @@ Revise /opt/project/composer.json
|
||||
}
|
||||
```
|
||||
|
||||
Finally, execute `composer update -o` in the directory `/opt/project`.
|
||||
最后在目录 `/opt/project` 中执行 `composer update -o` 即可。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,31 +1,31 @@
|
||||
# Guide Preface
|
||||
# 指南前言
|
||||
|
||||
In order to help developers better develop components for Hyperf and build an ecosystem together, we provide this guide to guide developers in component development. Before reading this guide, you need a **comprehensive** of Hyperf's documentation. Read, especially the [Coroutines](en/coroutine.md) and [Dependency Injection](en/di.md) chapters, a lack of a good understanding of the underlying components of Hyperf may lead to development errors.
|
||||
为了帮助开发者更好的为 Hyperf 开发组件,共建生态,我们提供了本指南用于指导开发者进行组件开发,在阅读本指南前,需要您对 Hyperf 的文档进行了 **全面** 的阅读,特别是 [协程](zh-cn/coroutine.md) 和 [依赖注入](zh-cn/di.md) 章节,如果对 Hyperf 的基础组件缺少充分的理解,可能会导致开发时出现错误。
|
||||
|
||||
# The purpose of component development
|
||||
# 组件开发的目的
|
||||
|
||||
In the development under the traditional PHP-FPM architecture, usually when we need to use third-party libraries to solve our needs, we will directly introduce a corresponding `Library` through Composer, but under Hyperf, due to `persistence' The two characteristics of `Application` and `Coroutine` lead to some differences in the life cycle and mode of the application, so not all `Library` can be used directly in Hyperf. Of course, some well-designed ones `Library` can also be used directly. After reading this guide, you will know how to identify whether some `Library` can be used directly in the project, and how to change it if not.
|
||||
在传统的 PHP-FPM 架构下的开发,通常在我们需要借助第三方库来解决我们的需求时,都会通过 Composer 来直接引入一个对应的 `库(Library)`,但是在 Hyperf 下,由于 `持久化应用` 和 `协程` 这两个特性,导致了应用的生命周期和模式存在一些差异,所以并不是所有的 `库(Library)` 都能在 Hyperf 里直接使用,当然,一些设计优秀的 `库(Library)` 也是可以被直接使用的。通读本指南,便可知道如何甄别一些 `库(Library)` 是否能直接用于项目内,不能的话该进行如何的改动。
|
||||
|
||||
# Component development preparation
|
||||
# 组件开发准备工作
|
||||
|
||||
The development preparation work referred to here, in addition to the basic operating conditions of Hyperf, focuses more on how to organize the structure of the code more conveniently to facilitate the development of components. Note that the following methods may not be able to jump due to *soft connections Problem* and does not apply to development environments under Windows for Docker.
|
||||
In terms of code organization, we recommend Clone [hyperf-cloud/hyperf-skeleton](https://github.com/hyperf-cloud/hyperf-skeleton) project skeleton and [hyperf-cloud/hyperf]( https://github.com/hyperf-cloud/hyperf) project component library two projects. Do the following and have the following structure:
|
||||
这里所指的开发准备工作,除了 Hyperf 的基础运行条件外,这里关注的更多是如何更加便捷的组织代码的结构以便于组件的开发工作,注意以下方式可能会由于 *软连接无法跳转的问题* 而并不适用于 Windows for Docker 下的开发环境。
|
||||
在代码组织上,我们建议在同一个目录下 Clone [hyperf/hyperf-skeleton](https://github.com/hyperf/hyperf-skeleton) 项目骨架和 [hyperf/hyperf](https://github.com/hyperf/hyperf) 项目组件库两个项目。进行下面的操作并呈以下结构:
|
||||
|
||||
```bash
|
||||
// Install the skeleton and configure it
|
||||
// 安装 skeleton,并配置完成
|
||||
composer create-project hyperf/hyperf-skeleton
|
||||
|
||||
// Clone the hyperf component library project, remember to replace hyperf-cloud with your Github ID, that is, clone the project you fork
|
||||
git clone git@github.com:hyperf-cloud/hyperf.git
|
||||
// 克隆 hyperf 组件库项目,这里记得要替换 hyperf 为您的 Github ID,也就是克隆您所 Fork 的项目
|
||||
git clone git@github.com:hyperf/hyperf.git
|
||||
```
|
||||
|
||||
Has the following structure:
|
||||
呈以下结构:
|
||||
|
||||
```
|
||||
.
|
||||
├── hyperf
|
||||
│ ├── bin
|
||||
│ └── src
|
||||
│ ├── bin
|
||||
│ └── src
|
||||
└── hyperf-skeleton
|
||||
├── app
|
||||
├── bin
|
||||
@ -35,7 +35,7 @@ Has the following structure:
|
||||
└── vendor
|
||||
```
|
||||
|
||||
The purpose of this is to make the `hyperf-skeleton` project available directly through the `path` source form, and let Composer directly pass the projects in the `hyperf` folder as dependencies to be loaded into the `vendor of the `hyperf-skelton` project ` directory, we add a `repositories` item to the `composer.json` file in `hyperf-skelton`, as follows:
|
||||
这样做的目的是为了让 `hyperf-skeleton` 项目可以直接通过 `path` 来源的形式,让 Composer 直接通过 `hyperf` 文件夹内的项目作为依赖项被加载到 `hyperf-skelton` 项目的 `vendor` 目录中,我们对 `hyperf-skelton` 内的 `composer.json` 文件增加一个 `repositories` 项,如下:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -43,7 +43,7 @@ The purpose of this is to make the `hyperf-skeleton` project available directly
|
||||
"hyperf": {
|
||||
"type": "path",
|
||||
"url": "../hyperf/src/*"
|
||||
}
|
||||
},
|
||||
"packagist": {
|
||||
"type": "composer",
|
||||
"url": "https://mirrors.aliyun.com/composer"
|
||||
@ -51,21 +51,21 @@ The purpose of this is to make the `hyperf-skeleton` project available directly
|
||||
}
|
||||
}
|
||||
```
|
||||
Then delete the `composer.lock` file and `vendor` folder in the `hyperf-skeleton` project, and then execute `composer update` to update the dependencies again, the command is as follows:
|
||||
然后再在 `hyperf-skeleton` 项目内删除 `composer.lock` 文件和 `vendor` 文件夹,再执行 `composer update` 让依赖重新更新,命令如下:
|
||||
|
||||
```bash
|
||||
cd hyperf-skeleton
|
||||
rm -rf composer.lock && rm -rf vendor && composer update
|
||||
```
|
||||
|
||||
Finally, the project folders in the `hyperf-skeleton/vendor/hyperf` folder are all connected to the `hyperf` folder through a `softlink`. We can use the `ls -l` command to verify whether the `softlink` has been established successfully:
|
||||
最终使 `hyperf-skeleton/vendor/hyperf` 文件夹内的项目文件夹全部通过 `软连接(softlink)` 连接到 `hyperf` 文件夹内。我们可以通过 `ls -l` 命令来验证 `软连接(softlink)` 是否已经建立成功:
|
||||
|
||||
```bash
|
||||
cd vendor/hyperf/
|
||||
ls -l
|
||||
```
|
||||
|
||||
When we see a connection relationship like the following, it means that the `softlink` has been established successfully:
|
||||
当我们看到类似下面这样的连接关系,即表明 `软连接(softlink)` 建立成功了:
|
||||
|
||||
```
|
||||
cache -> ../../../hyperf/src/cache
|
||||
@ -94,4 +94,4 @@ testing -> ../../../hyperf/src/testing
|
||||
utils -> ../../../hyperf/src/utils
|
||||
```
|
||||
|
||||
At this point, we can directly modify the files in `vendor/hyperf` in the IDE, but the code in `hyperf` is modified, so that we can directly modify the `hyperf` project. `commit`, and then submit a `Pull Request(PR)` to the trunk.
|
||||
此时,我们便可达到在 IDE 内直接对 `vendor/hyperf` 内的文件进行修改,而修改的却是 `hyperf` 内的代码的目的,这样最终我们便可直接对 `hyperf` 项目内进行 `commit`,然后向主干提交 `Pull Request(PR)` 了。
|
||||
|
@ -1,21 +1,71 @@
|
||||
# Model
|
||||
# 模型
|
||||
|
||||
Model components are derived from [Eloquent ORM](https://laravel.com/docs/5.8/eloquent), and related operations can refer to the Eloquent ORM documentation.
|
||||
模型组件衍生于 [Eloquent ORM](https://laravel.com/docs/5.8/eloquent),相关操作均可参考 Eloquent ORM 的文档。
|
||||
|
||||
## Create a model
|
||||
## 创建模型
|
||||
|
||||
Hyperf 提供了创建模型的命令,您可以很方便的根据数据表创建对应模型。命令通过 `AST` 生成模型,所以当您增加了某些方法后,也可以使用脚本方便的重置模型。
|
||||
|
||||
Hyperf provides commands to create models, and you can easily create corresponding models based on data tables. The command generates the model via `AST`, so when you add certain methods, you can also easily reset the model with a script.
|
||||
```
|
||||
$ php bin/hyperf.php db:model table_name
|
||||
php bin/hyperf.php gen:model table_name
|
||||
```
|
||||
|
||||
The created model is as follows
|
||||
可选参数如下:
|
||||
|
||||
| 参数 | 类型 | 默认值 | 备注 |
|
||||
| :----------------: | :----: | :-------------------------------: | :-----------------------------------------------: |
|
||||
| --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);
|
||||
|
||||
namespace App\Models;
|
||||
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;
|
||||
|
||||
@ -51,27 +101,29 @@ class User extends Model
|
||||
}
|
||||
```
|
||||
|
||||
## Model parameters
|
||||
## 模型成员变量
|
||||
|
||||
| parameter | type | defaults | Notes |
|
||||
|:----------:|:------:|:-------:|:--------------------:|
|
||||
| connection | string | default | Database Connectivity |
|
||||
| table | string | null | data table name |
|
||||
| primaryKey | string | id | model primary key |
|
||||
| keyType | string | int | primary key type |
|
||||
| fillable | array | [] | properties that are allowed to be bulk copied |
|
||||
| casts | string | null | data formatting configuration |
|
||||
| timestamps | bool | true | whether to automatically maintain timestamps |
|
||||
| 参数 | 类型 | 默认值 | 备注 |
|
||||
| :----------: | :----: | :-----: | :------------------: |
|
||||
| connection | string | default | 数据库连接 |
|
||||
| table | string | 无 | 数据表名称 |
|
||||
| primaryKey | string | id | 模型主键 |
|
||||
| keyType | string | int | 主键类型 |
|
||||
| fillable | array | [] | 允许被批量赋值的属性 |
|
||||
| casts | string | 无 | 数据格式化配置 |
|
||||
| timestamps | bool | true | 是否自动维护时间戳 |
|
||||
| incrementing | bool | true | 是否自增主键 |
|
||||
|
||||
### data table name
|
||||
### 数据表名称
|
||||
|
||||
如果我们没有指定模型对应的 table,它将使用类的复数形式「蛇形命名」来作为表名。因此,在这种情况下,Hyperf 将假设 User 模型存储的是 users 数据表中的数据。你可以通过在模型上定义 table 属性来指定自定义数据表:
|
||||
|
||||
If we don't specify the table corresponding to the model, it will use the plural form of the class "snake name" as the table name. So in this case Hyperf will assume that the User model stores data from the users data table. You can specify custom data tables by defining the table attribute on the model:
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
namespace App\Model;
|
||||
|
||||
use Hyperf\DbConnection\Model\Model;
|
||||
|
||||
@ -81,22 +133,22 @@ class User extends Model
|
||||
}
|
||||
```
|
||||
|
||||
### Primary key
|
||||
### 主键
|
||||
|
||||
Hyperf will assume that each data table has a primary key column named id. You can define a protected $primaryKey property to override the convention.
|
||||
Hyperf 会假设每个数据表都有一个名为 id 的主键列。你可以定义一个受保护的 $primaryKey 属性来重写约定。
|
||||
|
||||
Additionally, Hyperf assumes that the primary key is an auto-incrementing integer value, which means that the primary key is automatically converted to int by default. If you wish to use a non-incrementing or non-numeric primary key then you need to set the public $incrementing property to false. If your primary key is not an integer, you need to set the protected $keyType property on the model to string.
|
||||
此外,Hyperf 假设主键是一个自增的整数值,这意味着默认情况下主键会自动转换为 int 类型。如果您希望使用非递增或非数字的主键则需要设置公共的 $incrementing 属性设置为 false。如果你的主键不是一个整数,你需要将模型上受保护的 $keyType 属性设置为 string。
|
||||
|
||||
### Timestamp
|
||||
### 时间戳
|
||||
|
||||
By default, Hyperf expects `created_at` and `updated_at` to exist in your data table. If you don't want Hyperf to manage these two columns automatically, set the `$timestamps` property in the model to `false`:
|
||||
默认情况下,Hyperf 预期你的数据表中存在 `created_at` 和 `updated_at` 。如果你不想让 Hyperf 自动管理这两个列, 请将模型中的 `$timestamps` 属性设置为 `false`:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
namespace App\Model;
|
||||
|
||||
use Hyperf\DbConnection\Model\Model;
|
||||
|
||||
@ -106,14 +158,14 @@ class User extends Model
|
||||
}
|
||||
```
|
||||
|
||||
If you need a custom timestamp format, set the `$dateFormat` property on your model. This property determines how the date property is stored in the database, and the format in which the model is serialized as an array or JSON:
|
||||
如果需要自定义时间戳的格式,在你的模型中设置 `$dateFormat` 属性。这个属性决定日期属性在数据库的存储方式,以及模型序列化为数组或者 JSON 的格式:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
namespace App\Model;
|
||||
|
||||
use Hyperf\DbConnection\Model\Model;
|
||||
|
||||
@ -123,16 +175,16 @@ class User extends Model
|
||||
}
|
||||
```
|
||||
|
||||
If you need storage that you don't want to keep in `datetime` format, or want to do further processing of the time, you can do it by overriding the `fromDateTime($value)` method in the model.
|
||||
如果您需要不希望保持 `datetime` 格式的储存,或者希望对时间做进一步的处理,您可以通过在模型内重写 `fromDateTime($value)` 方法实现。
|
||||
|
||||
If you need to customize the field name for storing timestamps, you can do so by setting the values of the `CREATED_AT` and `UPDATED_AT` constants in the model, one of which is `null`, indicating that you do not want the ORM to process this field:
|
||||
如果你需要自定义存储时间戳的字段名,可以在模型中设置 `CREATED_AT` 和 `UPDATED_AT` 常量的值来实现,其中一个为 `null`,则表明不希望 ORM 处理该字段:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
namespace App\Model;
|
||||
|
||||
use Hyperf\DbConnection\Model\Model;
|
||||
|
||||
@ -144,15 +196,16 @@ class User extends Model
|
||||
}
|
||||
```
|
||||
|
||||
### Database Connectivity
|
||||
### 数据库连接
|
||||
|
||||
默认情况下,Hyperf 模型将使用你的应用程序配置的默认数据库连接 `default`。如果你想为模型指定一个不同的连接,设置 `$connection` 属性:当然,`connection-name` 作为 `key`,必须在 `databases.php` 配置文件中存在。
|
||||
|
||||
By default, the Hyperf model will use the default database connection `default` configured by your application. If you want to specify a different connection for the model, set the `$connection` property: of course, the `connection-name` as the `key` must exist in the `databases.php` configuration file.
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
namespace App\Model;
|
||||
|
||||
use Hyperf\DbConnection\Model\Model;
|
||||
|
||||
@ -162,15 +215,16 @@ class User extends Model
|
||||
}
|
||||
```
|
||||
|
||||
### Default property value
|
||||
### 默认属性值
|
||||
|
||||
如果要为模型的某些属性定义默认值,可以在模型上定义 `$attributes` 属性:
|
||||
|
||||
If you want to define default values for some attributes of the model, you can define the `$attributes` attribute on the model:
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
namespace App\Model;
|
||||
|
||||
use Hyperf\DbConnection\Model\Model;
|
||||
|
||||
@ -182,10 +236,11 @@ class User extends Model
|
||||
}
|
||||
```
|
||||
|
||||
## Model query
|
||||
## 模型查询
|
||||
|
||||
```php
|
||||
use App\Models\User;
|
||||
<?php
|
||||
use App\Model\User;
|
||||
|
||||
/** @var User $user */
|
||||
$user = User::query()->where('id', 1)->first();
|
||||
@ -194,11 +249,13 @@ $user->save();
|
||||
|
||||
```
|
||||
|
||||
### Reload model
|
||||
### 重新加载模型
|
||||
|
||||
你可以使用 `fresh` 和 `refresh` 方法重新加载模型。 `fresh` 方法会重新从数据库中检索模型。现有的模型实例不受影响:
|
||||
|
||||
You can reload the model using the `fresh` and `refresh` methods. The `fresh` method will retrieve the model from the database again. Existing model instances are not affected:
|
||||
```php
|
||||
use App\Models\User;
|
||||
<?php
|
||||
use App\Model\User;
|
||||
|
||||
/** @var User $user */
|
||||
$user = User::query()->find(1);
|
||||
@ -206,9 +263,11 @@ $user = User::query()->find(1);
|
||||
$freshUser = $user->fresh();
|
||||
```
|
||||
|
||||
The `refresh` method reassigns an existing model with new data from the database. Additionally, already loaded relationships are reloaded:
|
||||
`refresh` 方法使用数据库中的新数据重新赋值现有模型。此外,已经加载的关系会被重新加载:
|
||||
|
||||
```php
|
||||
use App\Models\User;
|
||||
<?php
|
||||
use App\Model\User;
|
||||
|
||||
/** @var User $user */
|
||||
$user = User::query()->where('name','Hyperf')->first();
|
||||
@ -220,67 +279,90 @@ $user->refresh();
|
||||
echo $user->name; // Hyperf
|
||||
```
|
||||
|
||||
### Gather
|
||||
### 集合
|
||||
|
||||
对于模型中的 `all` 和 `get` 方法可以查询多个结果,返回一个 `Hyperf\Database\Model\Collection` 实例。 `Collection` 类提供了很多辅助函数来处理查询结果:
|
||||
|
||||
For the `all` and `get` methods on the model to query multiple results, a `Hyperf\Database\Model\Collection` instance is returned. The `Collection` class provides a number of helper functions to process query results:
|
||||
```php
|
||||
$users = $users->reject(function ($user) {
|
||||
// Exclude all deleted users
|
||||
// 排除所有已删除的用户
|
||||
return $user->deleted;
|
||||
});
|
||||
```
|
||||
|
||||
### Retrieve a single model
|
||||
### 检索单个模型
|
||||
|
||||
除了从指定的数据表检索所有记录外,你可以使用 `find` 或 `first` 方法来检索单条记录。这些方法返回单个模型实例,而不是返回模型集合:
|
||||
|
||||
In addition to retrieving all records from a specified data table, you can use the `find` or `first` methods to retrieve a single record. Instead of returning a collection of models, these methods return a single model instance:
|
||||
```php
|
||||
use App\Models\User;
|
||||
<?php
|
||||
use App\Model\User;
|
||||
|
||||
$user = User::query()->where('id', 1)->first();
|
||||
|
||||
$user = User::query()->find(1);
|
||||
```
|
||||
|
||||
### Retrieve multiple models
|
||||
### 检索多个模型
|
||||
|
||||
当然 `find` 的方法不止支持单个模型。
|
||||
|
||||
Of course the `find` method supports more than just a single model.
|
||||
```php
|
||||
use App\Models\User;
|
||||
<?php
|
||||
use App\Model\User;
|
||||
|
||||
$users = User::query()->find([1, 2, 3]);
|
||||
```
|
||||
|
||||
### Aggregate function
|
||||
### 『未找到』异常
|
||||
|
||||
有时你希望在未找到模型时抛出异常,这在控制器和路由中非常有用。
|
||||
`findOrFail` 和 `firstOrFail` 方法会检索查询的第一个结果,如果未找到,将抛出 `Hyperf\Database\Model\ModelNotFoundException` 异常:
|
||||
|
||||
You can also use the `count`, `sum`, `max`, and other aggregate functions provided by the query builder. These methods will just return the appropriate scalar value instead of a model instance:
|
||||
```php
|
||||
use App\Models\User;
|
||||
<?php
|
||||
use App\Model\User;
|
||||
|
||||
$model = User::findOrFail(1);
|
||||
$model = User::where('age', '>', 18)->firstOrFail();
|
||||
```
|
||||
|
||||
### 聚合函数
|
||||
|
||||
你还可以使用 查询构造器 提供的 `count`,`sum`, `max`, 和其他的聚合函数。这些方法只会返回适当的标量值而不是一个模型实例:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use App\Model\User;
|
||||
|
||||
$count = User::query()->where('gender', 1)->count();
|
||||
```
|
||||
|
||||
## Insert & Update Model
|
||||
## 插入 & 更新模型
|
||||
|
||||
### Insert
|
||||
### 插入
|
||||
|
||||
要往数据库新增一条记录,先创建新模型实例,给实例设置属性,然后调用 `save` 方法:
|
||||
|
||||
To add a new record to the database, first create a new model instance, set properties on the instance, and then call the `save` method:
|
||||
```php
|
||||
use App\Models\User;
|
||||
use App\Model\User;
|
||||
|
||||
/** @var User $user */
|
||||
$user = new User();
|
||||
|
||||
$user->name = 'Hi Hyperf';
|
||||
$user->name = 'Hyperf';
|
||||
|
||||
$user->save();
|
||||
```
|
||||
|
||||
In this example, we assign to the `name` property of the `App\Models\User` model instance. When the `save` method is called, a new record will be inserted. `created_at` and `updated_at` timestamps will be set automatically, no manual assignment is required.
|
||||
### Update
|
||||
在这个示例中,我们赋值给了 `App\Model\User` 模型实例的 `name` 属性。当调用 `save` 方法时,将会插入一条新记录。 `created_at` 和 `updated_at` 时间戳将会自动设置,不需要手动赋值。
|
||||
|
||||
### 更新
|
||||
|
||||
`save` 方法也可以用来更新数据库已经存在的模型。更新模型,你需要先检索出来,设置要更新的属性,然后调用 `save` 方法。同样, `updated_at` 时间戳会自动更新,所以也不需要手动赋值:
|
||||
|
||||
The `save` method can also be used to update models that already exist in the database. To update the model, you need to retrieve it, set the properties to update, and then call the `save` method. Also, the `updated_at` timestamp is updated automatically, so no manual assignment is required:
|
||||
```php
|
||||
use App\Models\User;
|
||||
use App\Model\User;
|
||||
|
||||
/** @var User $user */
|
||||
$user = User::query()->find(1);
|
||||
@ -290,30 +372,32 @@ $user->name = 'Hi Hyperf';
|
||||
$user->save();
|
||||
```
|
||||
|
||||
### Bulk update
|
||||
### 批量更新
|
||||
|
||||
也可以更新匹配查询条件的多个模型。在这个示例中,所有的 `gender` 为 `1` 的用户,修改 `gender_show` 为 男性:
|
||||
|
||||
Multiple models matching the query criteria can also be updated. In this example, all users whose `gender` is 1, modify `gender_show` to be male:
|
||||
```php
|
||||
use App\Models\User;
|
||||
use App\Model\User;
|
||||
|
||||
User::query()->where('gender', 1)->update(['gender_show' => 'male']);
|
||||
User::query()->where('gender', 1)->update(['gender_show' => '男性']);
|
||||
```
|
||||
|
||||
> When batch updating, the updated model will not trigger saved and updated events. Because during batch updates, the model is never retrieved.
|
||||
### Mass assignment
|
||||
> 批量更新时, 更新的模型不会触发 `saved` 和 `updated` 事件。因为在批量更新时,并没有实例化模型。同时,也不会执行相应的 `casts`,例如数据库中 `json` 格式,在 Model 类中 `casts` 字段标记为 `array`,若是用批量更新,则插入时不会自动将 `array` 转换为 `json` 字符串格式。
|
||||
|
||||
You can also save a new model using the `create` method, which returns a model instance. However, you need to specify the `fillable` or `guarded` attribute on the model before using it, as all models are not mass-assignable by default.
|
||||
### 批量赋值
|
||||
|
||||
When a user passes in an unexpected parameter through an HTTP request, and that parameter changes a field in the database that you don't need to change. For example, a malicious user might pass the `is_admin` parameter in an HTTP request and then pass it to the `create` method, which allows the user to escalate themselves to admin.
|
||||
你也可以使用 `create` 方法来保存新模型,此方法会返回模型实例。不过,在使用之前,你需要在模型上指定 `fillable` 或 `guarded` 属性,因为所有的模型都默认不可进行批量赋值。
|
||||
|
||||
So, before you start, you should define which properties on the model can be mass-assigned. You can do this via the `$fillable` property on the model. For example, to make the `name` property of the `User` model mass assignable:
|
||||
当用户通过 HTTP 请求传入一个意外的参数,并且该参数更改了数据库中你不需要更改的字段时。比如:恶意用户可能会通过 HTTP 请求传入 `is_admin` 参数,然后将其传给 `create` 方法,此操作能让用户将自己升级成管理员。
|
||||
|
||||
所以,在开始之前,你应该定义好模型上的哪些属性是可以被批量赋值的。你可以通过模型上的 `$fillable` 属性来实现。 例如:让 `User` 模型的 `name` 属性可以被批量赋值:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
namespace App\Model;
|
||||
|
||||
use Hyperf\DbConnection\Model\Model;
|
||||
|
||||
@ -323,30 +407,30 @@ class User extends Model
|
||||
}
|
||||
```
|
||||
|
||||
Once we have set the properties that can be mass-assigned, we can insert new data into the database via the `create` method. The `create` method will return the saved model instance:
|
||||
一旦我们设置好了可以批量赋值的属性,就可以通过 `create` 方法插入新数据到数据库中了。 `create` 方法将返回保存的模型实例:
|
||||
|
||||
```php
|
||||
use App\Models\User;
|
||||
use App\Model\User;
|
||||
|
||||
$user = User::create(['name' => 'Hyperf']);
|
||||
```
|
||||
|
||||
If you already have a model instance, you can pass an array to the fill method to assign:
|
||||
如果你已经有一个模型实例,你可以传递一个数组给 fill 方法来赋值:
|
||||
|
||||
```php
|
||||
$user->fill(['name' => 'Hyperf']);
|
||||
```
|
||||
|
||||
### Protected properties
|
||||
### 保护属性
|
||||
|
||||
`$fillable` can be seen as a "whitelist" for mass assignment, and you can also use the `$guarded` attribute to achieve this. The `$guarded` property contains arrays that do not allow mass assignment. That is, `$guarded` will function more like a "blacklist". Note: You can only use either `$fillable` or `$guarded`, not both. In the following example, except for the `gender_show` attribute, all other attributes can be mass-assigned:
|
||||
`$fillable` 可以看作批量赋值的「白名单」, 你也可以使用 `$guarded` 属性来实现。 `$guarded` 属性包含的是不允许批量赋值的数组。也就是说, `$guarded` 从功能上将更像是一个「黑名单」。注意:你只能使用 `$fillable` 或 `$guarded` 二者中的一个,不可同时使用。下面这个例子中,除了 `gender_show` 属性,其他的属性都可以批量赋值:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
namespace App\Model;
|
||||
|
||||
use Hyperf\DbConnection\Model\Model;
|
||||
|
||||
@ -356,57 +440,129 @@ class User extends Model
|
||||
}
|
||||
```
|
||||
|
||||
### Delete model
|
||||
### 其他创建方法
|
||||
|
||||
Instances can be deleted by calling the `delete` method on a model instance:
|
||||
`firstOrCreate` / `firstOrNew`
|
||||
|
||||
这里有两个你可能用来批量赋值的方法: `firstOrCreate` 和 `firstOrNew`。
|
||||
|
||||
`firstOrCreate` 方法会通过给定的 列 / 值 来匹配数据库中的数据。如果在数据库中找不到对应的模型, 则会从第一个参数的属性乃至第二个参数的属性中创建一条记录插入到数据库。
|
||||
|
||||
`firstOrNew` 方法像 `firstOrCreate` 方法一样尝试通过给定的属性查找数据库中的记录。不同的是,如果 `firstOrNew` 方法找不到对应的模型,会返回一个新的模型实例。注意 `firstOrNew` 返回的模型实例尚未保存到数据库中,你需要手动调用 `save` 方法来保存:
|
||||
|
||||
```php
|
||||
use App\Models\User;
|
||||
<?php
|
||||
use App\Model\User;
|
||||
|
||||
// 通过 name 来查找用户,不存在则创建...
|
||||
$user = User::firstOrCreate(['name' => 'Hyperf']);
|
||||
|
||||
// 通过 name 查找用户,不存在则使用 name 和 gender, age 属性创建...
|
||||
$user = User::firstOrCreate(
|
||||
['name' => 'Hyperf'],
|
||||
['gender' => 1, 'age' => 20]
|
||||
);
|
||||
|
||||
// 通过 name 查找用户,不存在则创建一个实例...
|
||||
$user = User::firstOrNew(['name' => 'Hyperf']);
|
||||
|
||||
// 通过 name 查找用户,不存在则使用 name 和 gender, age 属性创建一个实例...
|
||||
$user = User::firstOrNew(
|
||||
['name' => 'Hyperf'],
|
||||
['gender' => 1, 'age' => 20]
|
||||
);
|
||||
```
|
||||
|
||||
### 删除模型
|
||||
|
||||
可以在模型实例上调用 `delete` 方法来删除实例:
|
||||
|
||||
```php
|
||||
use App\Model\User;
|
||||
|
||||
$user = User::query()->find(1);
|
||||
|
||||
$user->delete();
|
||||
```
|
||||
|
||||
### Delete model by query
|
||||
### 通过查询删除模型
|
||||
|
||||
You can delete model data by calling the `delete` method on the query, in this example we will delete all users whose `gender` is `1`. Like bulk updates, bulk deletes do not fire any model events for the deleted model:
|
||||
您可通过在查询上调用 `delete` 方法来删除模型数据,在这个例子中,我们将删除所有 `gender` 为 `1` 的用户。与批量更新一样,批量删除不会为删除的模型启动任何模型事件:
|
||||
|
||||
```php
|
||||
use App\Models\User;
|
||||
use App\Model\User;
|
||||
|
||||
// Note that when using the delete method, certain query conditions must be used to safely delete data. There is no where condition, which will cause the entire data table to be deleted.
|
||||
// 注意使用 delete 方法时必须建立在某些查询条件基础之上才能安全删除数据,不存在 where 条件,会导致删除整个数据表
|
||||
User::query()->where('gender', 1)->delete();
|
||||
```
|
||||
|
||||
### Delete data directly by primary key
|
||||
### 通过主键直接删除数据
|
||||
|
||||
在上面的例子中,在调用 `delete` 之前需要先去数据库中查找对应的模型。事实上,如果你知道了模型的主键,您可以直接通过 `destroy` 静态方法来删除模型数据,而不用先去数据库中查找。 `destroy` 方法除了接受单个主键作为参数之外,还接受多个主键,或者使用数组,集合来保存多个主键:
|
||||
|
||||
In the above example, before calling `delete`, you need to look up the corresponding model in the database. In fact, if you know the primary key of the model, you can delete the model data directly through the `destroy` static method without first looking in the database. In addition to accepting a single primary key as a parameter, the `destroy` method also accepts multiple primary keys, or uses arrays, collections to store multiple primary keys:
|
||||
```php
|
||||
use App\Models\User;
|
||||
use App\Model\User;
|
||||
|
||||
User::destroy(1);
|
||||
|
||||
User::destroy([1,2,3]);
|
||||
```
|
||||
|
||||
### Soft delete
|
||||
### 软删除
|
||||
|
||||
In addition to actually deleting database records, `Hyperf` can also "soft delete" the model. Soft deleted models are not really deleted from the database. In fact, the `deleted_at` attribute is set on the model and its value is written to the database. If the `deleted_at` value is non-null, it means the model has been soft deleted. To enable model soft deletes, you need to use the `Hyperf\Database\Model\SoftDeletes` trait on the model
|
||||
除了真实删除数据库记录,`Hyperf` 也可以「软删除」模型。软删除的模型并不是真的从数据库中删除了。事实上,是在模型上设置了 `deleted_at` 属性并将其值写入数据库。如果 `deleted_at` 值非空,代表这个模型已被软删除。如果要开启模型软删除功能,你需要在模型上使用 `Hyperf\Database\Model\SoftDeletes` trait
|
||||
|
||||
> `SoftDeletes` trait will automatically convert `deleted_at` attributes to `DateTime / Carbon` instances
|
||||
> `SoftDeletes` trait 会自动将 `deleted_at` 属性转换成 `DateTime / Carbon` 实例
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
namespace App\Model;
|
||||
|
||||
use Hyperf\Database\Model\Model;
|
||||
use Hyperf\Database\Model\SoftDeletes;
|
||||
|
||||
class Flight extends Model
|
||||
class User extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Bit 类型
|
||||
|
||||
默认情况下,Hyperf 中的数据库模型转 SQL 过程中,会将参数值统一转为 String 类型,以解决 int 在大数问题和使值类型更容易匹配索引,若想要使 `ORM` 支持 `bit` 类型,只需要增加以下事件监听器代码即可。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Listener;
|
||||
|
||||
use Hyperf\Database\Connection;
|
||||
use Hyperf\Database\MySqlBitConnection;
|
||||
use Hyperf\Event\Annotation\Listener;
|
||||
use Hyperf\Event\Contract\ListenerInterface;
|
||||
use Hyperf\Framework\Event\BootApplication;
|
||||
|
||||
/**
|
||||
* @Listener()
|
||||
*/
|
||||
class SupportMySQLBitListener implements ListenerInterface
|
||||
{
|
||||
public function listen(): array
|
||||
{
|
||||
return [
|
||||
BootApplication::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function process(object $event)
|
||||
{
|
||||
Connection::resolverFor('mysql', static function ($connection, $database, $prefix, $config) {
|
||||
return new MySqlBitConnection($connection, $database, $prefix, $config);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
```
|
@ -4,7 +4,7 @@
|
||||
|
||||
| Version | Status | End of mainstream support | End of Security-fixes support | Release Date (or estimated date) |
|
||||
| ------- |-------------------------------------|---------------------------|-------------------------------|----------------------------------|
|
||||
| 3.0 | Developing (RC17 has been released) | 2023-06-30 | 2023-12-31 | About 2022-12-31 |
|
||||
| 3.0 | Developing (RC17 has been released) | 2023-06-30 | 2024-06-30 | About 2022-12-31 |
|
||||
| 2.2 | Security fixes support | 2022-06-20 | 2023-6-30 | 2021-07-19 |
|
||||
| 2.1 | Deprecated | 2021-06-30 | 2021-12-31 | 2020-12-28 |
|
||||
| 2.0 | Deprecated | 2020-12-28 | 2021-06-30 | 2020-06-22 |
|
||||
|
@ -7,7 +7,7 @@
|
||||
Hyperf 提供了创建模型的命令,您可以很方便的根据数据表创建对应模型。命令通过 `AST` 生成模型,所以当您增加了某些方法后,也可以使用脚本方便的重置模型。
|
||||
|
||||
```
|
||||
$ php bin/hyperf.php gen:model table_name
|
||||
php bin/hyperf.php gen:model table_name
|
||||
```
|
||||
|
||||
可选参数如下:
|
||||
@ -527,3 +527,42 @@ class User extends Model
|
||||
use SoftDeletes;
|
||||
}
|
||||
```
|
||||
|
||||
## Bit 类型
|
||||
|
||||
默认情况下,Hyperf 中的数据库模型转 SQL 过程中,会将参数值统一转为 String 类型,以解决 int 在大数问题和使值类型更容易匹配索引,若想要使 `ORM` 支持 `bit` 类型,只需要增加以下事件监听器代码即可。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Listener;
|
||||
|
||||
use Hyperf\Database\Connection;
|
||||
use Hyperf\Database\MySqlBitConnection;
|
||||
use Hyperf\Event\Annotation\Listener;
|
||||
use Hyperf\Event\Contract\ListenerInterface;
|
||||
use Hyperf\Framework\Event\BootApplication;
|
||||
|
||||
/**
|
||||
* @Listener()
|
||||
*/
|
||||
class SupportMySQLBitListener implements ListenerInterface
|
||||
{
|
||||
public function listen(): array
|
||||
{
|
||||
return [
|
||||
BootApplication::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function process(object $event)
|
||||
{
|
||||
Connection::resolverFor('mysql', static function ($connection, $database, $prefix, $config) {
|
||||
return new MySqlBitConnection($connection, $database, $prefix, $config);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
@ -182,44 +182,6 @@ use Hyperf\Utils\Coordinator\Constants;
|
||||
CoordinatorManager::until(Constants::WORKER_EXIT)->resume();
|
||||
```
|
||||
|
||||
|
||||
## ORM 不支持 bit 类型
|
||||
|
||||
若想要使 `ORM` 支持 `bit` 类型,只需要增加以下监听器代码即可。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Listener;
|
||||
|
||||
use Hyperf\Database\Connection;
|
||||
use Hyperf\Database\MySqlBitConnection;
|
||||
use Hyperf\Event\Annotation\Listener;
|
||||
use Hyperf\Event\Contract\ListenerInterface;
|
||||
use Hyperf\Framework\Event\BootApplication;
|
||||
|
||||
#[Listener]
|
||||
class SupportMySQLBitListener implements ListenerInterface
|
||||
{
|
||||
public function listen(): array
|
||||
{
|
||||
return [
|
||||
BootApplication::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function process(object $event)
|
||||
{
|
||||
Connection::resolverFor('mysql', static function ($connection, $database, $prefix, $config) {
|
||||
return new MySqlBitConnection($connection, $database, $prefix, $config);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## OSS 上传组件报 iconv 错误
|
||||
|
||||
- fix aliyun oss wrong charset: https://github.com/aliyun/aliyun-oss-php-sdk/issues/101
|
||||
|
@ -2,14 +2,14 @@
|
||||
|
||||
## 版本生命周期
|
||||
|
||||
| 版本 | 状态 | 积极支持截止时间 | 安全维护截止时间 | 发布或预计发布时间 |
|
||||
| ---- |----------------|------------|------------|---------------|
|
||||
| 3.0 | 研发中 (RC17 已发布) | 2023-06-30 | 2023-12-31 | 大概 2022-12-31 |
|
||||
| 2.2 | 安全维护 | 2022-06-20 | 2023-06-30 | 2021-07-19 |
|
||||
| 2.1 | 停止维护 | 2021-06-30 | 2021-12-31 | 2020-12-28 |
|
||||
| 2.0 | 停止维护 | 2020-12-28 | 2021-06-30 | 2020-06-22 |
|
||||
| 1.1 | 停止维护 | 2020-06-23 | 2020-12-31 | 2019-10-08 |
|
||||
| 1.0 | 停止维护 | 2019-10-08 | 2019-12-31 | 2019-06-20 |
|
||||
| 版本 | 状态 | 积极支持截止时间 | 安全维护截止时间 | 发布或预计发布时间 |
|
||||
| ---- |----------------|------------|------------|--------------|
|
||||
| 3.0 | 研发中 (RC17 已发布) | 2023-06-30 | 2024-06-30 | 大概 2022-12-31 |
|
||||
| 2.2 | 安全维护 | 2022-06-20 | 2023-06-30 | 2021-07-19 |
|
||||
| 2.1 | 停止维护 | 2021-06-30 | 2021-12-31 | 2020-12-28 |
|
||||
| 2.0 | 停止维护 | 2020-12-28 | 2021-06-30 | 2020-06-22 |
|
||||
| 1.1 | 停止维护 | 2020-06-23 | 2020-12-31 | 2019-10-08 |
|
||||
| 1.0 | 停止维护 | 2019-10-08 | 2019-12-31 | 2019-06-20 |
|
||||
|
||||
* 积极支持将包含常规迭代周期的 BUG 修复、安全问题修复、功能迭代和功能新增;
|
||||
* 安全维护仅包含安全问题的修复;
|
||||
|
@ -7,7 +7,7 @@
|
||||
Hyperf 提供了創建模型的命令,您可以很方便的根據數據表創建對應模型。命令通過 `AST` 生成模型,所以當您增加了某些方法後,也可以使用腳本方便的重置模型。
|
||||
|
||||
```
|
||||
$ php bin/hyperf.php gen:model table_name
|
||||
php bin/hyperf.php gen:model table_name
|
||||
```
|
||||
|
||||
可選參數如下:
|
||||
@ -527,3 +527,42 @@ class User extends Model
|
||||
use SoftDeletes;
|
||||
}
|
||||
```
|
||||
|
||||
## Bit 類型
|
||||
|
||||
默認情況下,Hyperf 中的數據庫模型轉 SQL 過程中,會將參數值統一轉為 String 類型,以解決 int 在大數問題和使值類型更容易匹配索引,若想要使 `ORM` 支持 `bit` 類型,只需要增加以下事件監聽器代碼即可。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Listener;
|
||||
|
||||
use Hyperf\Database\Connection;
|
||||
use Hyperf\Database\MySqlBitConnection;
|
||||
use Hyperf\Event\Annotation\Listener;
|
||||
use Hyperf\Event\Contract\ListenerInterface;
|
||||
use Hyperf\Framework\Event\BootApplication;
|
||||
|
||||
/**
|
||||
* @Listener()
|
||||
*/
|
||||
class SupportMySQLBitListener implements ListenerInterface
|
||||
{
|
||||
public function listen(): array
|
||||
{
|
||||
return [
|
||||
BootApplication::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function process(object $event)
|
||||
{
|
||||
Connection::resolverFor('mysql', static function ($connection, $database, $prefix, $config) {
|
||||
return new MySqlBitConnection($connection, $database, $prefix, $config);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
```
|
@ -182,44 +182,6 @@ use Hyperf\Utils\Coordinator\Constants;
|
||||
CoordinatorManager::until(Constants::WORKER_EXIT)->resume();
|
||||
```
|
||||
|
||||
|
||||
## ORM 不支持 bit 類型
|
||||
|
||||
若想要使 `ORM` 支持 `bit` 類型,只需要增加以下監聽器代碼即可。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Listener;
|
||||
|
||||
use Hyperf\Database\Connection;
|
||||
use Hyperf\Database\MySqlBitConnection;
|
||||
use Hyperf\Event\Annotation\Listener;
|
||||
use Hyperf\Event\Contract\ListenerInterface;
|
||||
use Hyperf\Framework\Event\BootApplication;
|
||||
|
||||
#[Listener]
|
||||
class SupportMySQLBitListener implements ListenerInterface
|
||||
{
|
||||
public function listen(): array
|
||||
{
|
||||
return [
|
||||
BootApplication::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function process(object $event)
|
||||
{
|
||||
Connection::resolverFor('mysql', static function ($connection, $database, $prefix, $config) {
|
||||
return new MySqlBitConnection($connection, $database, $prefix, $config);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## OSS 上傳組件報 iconv 錯誤
|
||||
|
||||
- fix aliyun oss wrong charset: https://github.com/aliyun/aliyun-oss-php-sdk/issues/101
|
||||
|
@ -2,14 +2,14 @@
|
||||
|
||||
## 版本生命週期
|
||||
|
||||
| 版本 | 狀態 | 積極支持截止時間 | 安全維護截止時間 | 發佈或預計發佈時間 |
|
||||
| ---- |----------------|------------|------------|---------------|
|
||||
| 3.0 | 研發中 (RC17 已發佈) | 2023-06-30 | 2023-12-31 | 大概 2022-12-31 |
|
||||
| 2.2 | 安全維護 | 2022-06-20 | 2023-06-30 | 2021-07-19 |
|
||||
| 2.1 | 停止維護 | 2021-06-30 | 2021-12-31 | 2020-12-28 |
|
||||
| 2.0 | 停止維護 | 2020-12-28 | 2021-06-30 | 2020-06-22 |
|
||||
| 1.1 | 停止維護 | 2020-06-23 | 2020-12-31 | 2019-10-08 |
|
||||
| 1.0 | 停止維護 | 2019-10-08 | 2019-12-31 | 2019-06-20 |
|
||||
| 版本 | 狀態 | 積極支持截止時間 | 安全維護截止時間 | 發佈或預計發佈時間 |
|
||||
| ---- |----------------|------------|------------|--------------|
|
||||
| 3.0 | 研發中 (RC17 已發佈) | 2023-06-30 | 2024-06-30 | 大概 2022-12-31 |
|
||||
| 2.2 | 安全維護 | 2022-06-20 | 2023-06-30 | 2021-07-19 |
|
||||
| 2.1 | 停止維護 | 2021-06-30 | 2021-12-31 | 2020-12-28 |
|
||||
| 2.0 | 停止維護 | 2020-12-28 | 2021-06-30 | 2020-06-22 |
|
||||
| 1.1 | 停止維護 | 2020-06-23 | 2020-12-31 | 2019-10-08 |
|
||||
| 1.0 | 停止維護 | 2019-10-08 | 2019-12-31 | 2019-06-20 |
|
||||
|
||||
* 積極支持將包含常規迭代週期的 BUG 修復、安全問題修復、功能迭代和功能新增;
|
||||
* 安全維護僅包含安全問題的修復;
|
||||
|
@ -7,7 +7,7 @@
|
||||
Hyperf 提供了建立模型的命令,您可以很方便的根據資料表建立對應模型。命令通過 `AST` 生成模型,所以當您增加了某些方法後,也可以使用指令碼方便的重置模型。
|
||||
|
||||
```
|
||||
$ php bin/hyperf.php gen:model table_name
|
||||
php bin/hyperf.php gen:model table_name
|
||||
```
|
||||
|
||||
可選引數如下:
|
||||
@ -527,3 +527,42 @@ class User extends Model
|
||||
use SoftDeletes;
|
||||
}
|
||||
```
|
||||
|
||||
## Bit 型別
|
||||
|
||||
預設情況下,Hyperf 中的資料庫模型轉 SQL 過程中,會將引數值統一轉為 String 型別,以解決 int 在大數問題和使值型別更容易匹配索引,若想要使 `ORM` 支援 `bit` 型別,只需要增加以下事件監聽器程式碼即可。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Listener;
|
||||
|
||||
use Hyperf\Database\Connection;
|
||||
use Hyperf\Database\MySqlBitConnection;
|
||||
use Hyperf\Event\Annotation\Listener;
|
||||
use Hyperf\Event\Contract\ListenerInterface;
|
||||
use Hyperf\Framework\Event\BootApplication;
|
||||
|
||||
/**
|
||||
* @Listener()
|
||||
*/
|
||||
class SupportMySQLBitListener implements ListenerInterface
|
||||
{
|
||||
public function listen(): array
|
||||
{
|
||||
return [
|
||||
BootApplication::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function process(object $event)
|
||||
{
|
||||
Connection::resolverFor('mysql', static function ($connection, $database, $prefix, $config) {
|
||||
return new MySqlBitConnection($connection, $database, $prefix, $config);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
```
|
@ -182,44 +182,6 @@ use Hyperf\Utils\Coordinator\Constants;
|
||||
CoordinatorManager::until(Constants::WORKER_EXIT)->resume();
|
||||
```
|
||||
|
||||
|
||||
## ORM 不支援 bit 型別
|
||||
|
||||
若想要使 `ORM` 支援 `bit` 型別,只需要增加以下監聽器程式碼即可。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Listener;
|
||||
|
||||
use Hyperf\Database\Connection;
|
||||
use Hyperf\Database\MySqlBitConnection;
|
||||
use Hyperf\Event\Annotation\Listener;
|
||||
use Hyperf\Event\Contract\ListenerInterface;
|
||||
use Hyperf\Framework\Event\BootApplication;
|
||||
|
||||
#[Listener]
|
||||
class SupportMySQLBitListener implements ListenerInterface
|
||||
{
|
||||
public function listen(): array
|
||||
{
|
||||
return [
|
||||
BootApplication::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function process(object $event)
|
||||
{
|
||||
Connection::resolverFor('mysql', static function ($connection, $database, $prefix, $config) {
|
||||
return new MySqlBitConnection($connection, $database, $prefix, $config);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## OSS 上傳元件報 iconv 錯誤
|
||||
|
||||
- fix aliyun oss wrong charset: https://github.com/aliyun/aliyun-oss-php-sdk/issues/101
|
||||
|
@ -2,14 +2,14 @@
|
||||
|
||||
## 版本生命週期
|
||||
|
||||
| 版本 | 狀態 | 積極支援截止時間 | 安全維護截止時間 | 釋出或預計釋出時間 |
|
||||
| ---- |----------------|------------|------------|---------------|
|
||||
| 3.0 | 研發中 (RC17 已釋出) | 2023-06-30 | 2023-12-31 | 大概 2022-12-31 |
|
||||
| 2.2 | 安全維護 | 2022-06-20 | 2023-06-30 | 2021-07-19 |
|
||||
| 2.1 | 停止維護 | 2021-06-30 | 2021-12-31 | 2020-12-28 |
|
||||
| 2.0 | 停止維護 | 2020-12-28 | 2021-06-30 | 2020-06-22 |
|
||||
| 1.1 | 停止維護 | 2020-06-23 | 2020-12-31 | 2019-10-08 |
|
||||
| 1.0 | 停止維護 | 2019-10-08 | 2019-12-31 | 2019-06-20 |
|
||||
| 版本 | 狀態 | 積極支援截止時間 | 安全維護截止時間 | 釋出或預計釋出時間 |
|
||||
| ---- |----------------|------------|------------|--------------|
|
||||
| 3.0 | 研發中 (RC17 已釋出) | 2023-06-30 | 2024-06-30 | 大概 2022-12-31 |
|
||||
| 2.2 | 安全維護 | 2022-06-20 | 2023-06-30 | 2021-07-19 |
|
||||
| 2.1 | 停止維護 | 2021-06-30 | 2021-12-31 | 2020-12-28 |
|
||||
| 2.0 | 停止維護 | 2020-12-28 | 2021-06-30 | 2020-06-22 |
|
||||
| 1.1 | 停止維護 | 2020-06-23 | 2020-12-31 | 2019-10-08 |
|
||||
| 1.0 | 停止維護 | 2019-10-08 | 2019-12-31 | 2019-06-20 |
|
||||
|
||||
* 積極支援將包含常規迭代週期的 BUG 修復、安全問題修復、功能迭代和功能新增;
|
||||
* 安全維護僅包含安全問題的修復;
|
||||
|
Loading…
Reference in New Issue
Block a user