首页
下载
文档
问答社区
视频
捐赠
源代码
AI 助理
赞助商
CRMEB
Apipost
腾讯云
微擎
禅道
51Talk
商业产品
Swoole AI 智能文档翻译器
Swoole-Compiler PHP 代码加密器
CRMEB 新零售社交电商系统
登录
注册
全部
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
发表新帖
在 Hyperf 框架中,如何定制 gen:model 命令
`Hyperf v2.0` 版本中,会将 `decimal` 转化为 `float`,从而存在精度丢失的风险。如果直接修改这个问题,可能会导致 `v2.0` 出现 `BC`,所以我们在 `v2.1` 中得到了处理,详情可见 [PR#2979](https://github.com/hyperf/hyperf/pull/2979) 但还在使用 `v2.0` 版本的同学要怎么办呢?
发布于3年前 · 21 次浏览 · 来自
开发框架
李铭昕
`Hyperf v2.0` 版本中,会将 `decimal` 转化为 `float`,从而存在精度丢失的风险。如果直接修改这个问题,可能会导致 `v2.0` 出现 `BC`,所以我们在 `v2.1` 中得到了处理,详情可见 [PR#2979](https://github.com/hyperf/hyperf/pull/2979) 但还在使用 `v2.0` 版本的同学要怎么办呢?
赞
0
分享
收藏
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
评论
2020-12-16
李铭昕
其实我们可以通过重写 `ModelUpdateVisitor`,很简单的处理这件事。 ## 创建模型 我们先在原来的情况下,执行 `gen:model`,为了后面高度定制,我们先将 `$timestamps` 设置为 `false`,这样 `created_at` 和 `updated_at` 默认都会转化为 `string`。 以下为生成的模型: ```php <?php declare(strict_types=1); /** * This file is part of Hyperf. * * [[[[[[@link ](/u/22784)](/u/22784)](/u/22784)](/u/22784)](/u/22784)](/u/22784) https://www.hyperf.io * @document https://hyperf.wiki * @contact group@hyperf.io * @license https://github.com/hyperf/hyperf/blob/master/LICENSE */ namespace App\Model; /** * @property int $id * @property int $count * @property float $float_num * @property string $str * @property string $json * @property string $created_at * @property string $updated_at */ class UserExt extends Model { public $timestamps = false; /** * The table associated with the model. * * [[[[[[[[[@var ](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)string */ protected $table = 'user_ext'; /** * The attributes that are mass assignable. * * [[[[[[[[[@var ](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)array */ protected $fillable = ['id', 'count', 'float_num', 'str', 'json', 'created_at', 'updated_at']; /** * The attributes that should be cast to native types. * * [[[[[[[[[@var ](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)array */ protected $casts = ['id' => 'integer', 'count' => 'integer', 'float_num' => 'float']; } ``` 我们可以看到,`float_num` 会被 `cast` 强制转化为 `float`。 ## 重写 ModelUpdateVisitor 接下来我们重写 `ModelUpdateVisitor`,将以下注释的代码删掉。 ``` <?php declare(strict_types=1); /** * This file is part of Hyperf. * * [[[[[[@link ](/u/22784)](/u/22784)](/u/22784)](/u/22784)](/u/22784)](/u/22784) https://www.hyperf.io * @document https://hyperf.wiki * @contact group@hyperf.io * @license https://github.com/hyperf/hyperf/blob/master/LICENSE */ namespace App\Visitor; use Hyperf\Database\Commands\Ast\ModelUpdateVisitor as Visitor; class ModelUpdateVisitor extends Visitor { protected function formatDatabaseType(string $type): ?string { switch ($type) { case 'tinyint': case 'smallint': case 'mediumint': case 'int': case 'bigint': return 'integer'; // case 'decimal': // case 'float': // case 'double': // case 'real': // return 'float'; case 'bool': case 'boolean': return 'boolean'; default: return null; } } } ``` 然后将其配置到 `dependencies.php` 中: ```php <?php declare(strict_types=1); /** * This file is part of Hyperf. * * [[[[[[@link ](/u/22784)](/u/22784)](/u/22784)](/u/22784)](/u/22784)](/u/22784) https://www.hyperf.io * @document https://hyperf.wiki * @contact group@hyperf.io * @license https://github.com/hyperf/hyperf/blob/master/LICENSE */ return [ Hyperf\Database\Commands\Ast\ModelUpdateVisitor::class => App\Visitor\ModelUpdateVisitor::class, ]; ``` 然后让我们重新执行 `php bin/hyperf.php gen:model --force-casts`,就可以看到,对应的 `float_num` 已经不会再转化成 `float` 了。 ```php <?php declare (strict_types=1); /** * This file is part of Hyperf. * * [[[[[[@link ](/u/22784)](/u/22784)](/u/22784)](/u/22784)](/u/22784)](/u/22784) https://www.hyperf.io * @document https://hyperf.wiki * @contact group@hyperf.io * @license https://github.com/hyperf/hyperf/blob/master/LICENSE */ namespace App\Model; /** * @property int $id * @property int $count * @property string $float_num * @property string $str * @property string $json * @property string $created_at * @property string $updated_at */ class UserExt extends Model { public $timestamps = false; /** * The table associated with the model. * * [[[[[[[[[@var ](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)string */ protected $table = 'user_ext'; /** * The attributes that are mass assignable. * * [[[[[[[[[@var ](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)array */ protected $fillable = ['id', 'count', 'float_num', 'str', 'json', 'created_at', 'updated_at']; /** * The attributes that should be cast to native types. * * [[[[[[[[[@var ](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)array */ protected $casts = ['id' => 'integer', 'count' => 'integer']; } ``` 当然除此之外,我们也可以通过这种方式,自动处理 `json` 和 `datetime` 格式,修改我们的 `ModelUpdateVisitor` ```php <?php declare(strict_types=1); /** * This file is part of Hyperf. * * [[[[[[@link ](/u/22784)](/u/22784)](/u/22784)](/u/22784)](/u/22784)](/u/22784) https://www.hyperf.io * @document https://hyperf.wiki * @contact group@hyperf.io * @license https://github.com/hyperf/hyperf/blob/master/LICENSE */ namespace App\Visitor; use Hyperf\Database\Commands\Ast\ModelUpdateVisitor as Visitor; class ModelUpdateVisitor extends Visitor { protected function formatDatabaseType(string $type): ?string { switch ($type) { case 'tinyint': case 'smallint': case 'mediumint': case 'int': case 'bigint': return 'integer'; case 'timestamp': case 'datetime': return 'datetime'; case 'json': return 'json'; case 'bool': case 'boolean': return 'boolean'; default: return null; } } } ``` 然后重新执行 `php bin/hyperf.php gen:model --force-casts`,就可以看到结果了。 ```php <?php declare(strict_types=1); /** * This file is part of Hyperf. * * [[[[[[@link ](/u/22784)](/u/22784)](/u/22784)](/u/22784)](/u/22784)](/u/22784) https://www.hyperf.io * @document https://hyperf.wiki * @contact group@hyperf.io * @license https://github.com/hyperf/hyperf/blob/master/LICENSE */ namespace App\Model; /** * @property int $id * @property int $count * @property string $float_num * @property string $str * @property array $json * @property \Carbon\Carbon $created_at * @property \Carbon\Carbon $updated_at */ class UserExt extends Model { public $timestamps = false; /** * The table associated with the model. * * [[[[[[[[[@var ](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)string */ protected $table = 'user_ext'; /** * The attributes that are mass assignable. * * [[[[[[[[[@var ](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)array */ protected $fillable = ['id', 'count', 'float_num', 'str', 'json', 'created_at', 'updated_at']; /** * The attributes that should be cast to native types. * * [[[[[[[[[@var ](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)](/u/3588)array */ protected $casts = ['id' => 'integer', 'count' => 'integer', 'json' => 'json', 'created_at' => 'datetime', 'updated_at' => 'datetime']; } ```
赞
1
回复
微信公众号
热门内容
作者其它话题
- 如何基于 Channel 实现多路复用
暂无回复的问答
- CodeGalaxy K3s 轻量集群节点之间如何实现负载均衡
- 关于openssl CURL WARNING swSSL_connect: SSL_connect(fd=69) failed. Error: error:141A318A:SSL routines:tls_process_ske_dhe:dh key too small[1|394]
- 多个模型如何进行事务异常回退?
- websocket开启wss报错
- 协程tcp服务器如何使用多进程?recv()方法接收信息,打印出来的pid一直是同一个。没用使用到多进程啊。