模型创建脚本

Hyperf 提供了创建模型的命令,您可以很方便的根据数据表创建对应模型。命令通过 AST 生成模型,所以当您增加了某些方法后,也可以使用脚本方便的重置模型。

  1. 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 中,如下

中划线都需要转化为下划线

  1. <?php
  2. declare(strict_types=1);
  3. use Hyperf\Database\Commands\ModelOption;
  4. return [
  5. 'default' => [
  6. // 忽略其他配置
  7. 'commands' => [
  8. 'gen:model' => [
  9. 'path' => 'app/Model',
  10. 'force_casts' => true,
  11. 'inheritance' => 'Model',
  12. 'uses' => '',
  13. 'refresh_fillable' => true,
  14. 'table_mapping' => [],
  15. 'with_comments' => true,
  16. 'property_case' => ModelOption::PROPERTY_SNAKE_CASE,
  17. ],
  18. ],
  19. ],
  20. ];

创建的模型如下

  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Model;
  4. use Hyperf\DbConnection\Model\Model;
  5. /**
  6. * @property $id
  7. * @property $name
  8. * @property $gender
  9. * @property $created_at
  10. * @property $updated_at
  11. */
  12. class User extends Model
  13. {
  14. /**
  15. * The table associated with the model.
  16. *
  17. * @var string
  18. */
  19. protected $table = 'user';
  20. /**
  21. * The attributes that are mass assignable.
  22. *
  23. * @var array
  24. */
  25. protected $fillable = ['id', 'name', 'gender', 'created_at', 'updated_at'];
  26. /**
  27. * The attributes that should be cast to native types.
  28. *
  29. * @var array
  30. */
  31. protected $casts = ['id' => 'integer', 'gender' => 'integer'];
  32. }

Visitors

框架提供了几个 Visitors,方便用户对脚本能力进行扩展。使用方法很简单,只需要在 visitors 配置中,添加对应的 Visitor 即可。

  1. <?php
  2. declare(strict_types=1);
  3. return [
  4. 'default' => [
  5. // 忽略其他配置
  6. 'commands' => [
  7. 'gen:model' => [
  8. 'visitors' => [
  9. Hyperf\Database\Commands\Ast\ModelRewriteKeyInfoVisitor::class
  10. ],
  11. ],
  12. ],
  13. ],
  14. ];

可选 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_atupdated_at 自动判断,是否启用默认记录 创建和修改时间 的功能。

  • Hyperf\Database\Commands\Ast\ModelRewriteGetterSetterVisitor

Visitor 可以根据数据库字段生成对应的 gettersetter

覆盖 Visitor

Hyperf 框架中,当使用 gen:model 时,默认会将 decimal 转化成为 float。如下:

  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Model;
  4. /**
  5. * @property int $id
  6. * @property int $count
  7. * @property float $float_num // decimal
  8. * @property string $str
  9. * @property string $json
  10. * @property \Carbon\Carbon $created_at
  11. * @property \Carbon\Carbon $updated_at
  12. */
  13. class UserExt extends Model
  14. {
  15. /**
  16. * The table associated with the model.
  17. *
  18. * @var string
  19. */
  20. protected $table = 'user_ext';
  21. /**
  22. * The attributes that are mass assignable.
  23. *
  24. * @var array
  25. */
  26. protected $fillable = ['id', 'count', 'float_num', 'str', 'json', 'created_at', 'updated_at'];
  27. /**
  28. * The attributes that should be cast to native types.
  29. *
  30. * @var array
  31. */
  32. protected $casts = ['id' => 'integer', 'count' => 'integer', 'float_num' => 'float', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
  33. }

这时候,我们就可以通过重写 ModelUpdateVisitor,修改这一特性。

  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * This file is part of Hyperf.
  5. *
  6. * @link https://www.hyperf.io
  7. * @document https://hyperf.wiki
  8. * @contact group@hyperf.io
  9. * @license https://github.com/hyperf/hyperf/blob/master/LICENSE
  10. */
  11. namespace App\Kernel\Visitor;
  12. use Hyperf\Database\Commands\Ast\ModelUpdateVisitor as Visitor;
  13. use Hyperf\Utils\Str;
  14. class ModelUpdateVisitor extends Visitor
  15. {
  16. protected function formatDatabaseType(string $type): ?string
  17. {
  18. switch ($type) {
  19. case 'tinyint':
  20. case 'smallint':
  21. case 'mediumint':
  22. case 'int':
  23. case 'bigint':
  24. return 'integer';
  25. case 'decimal':
  26. // 设置为 decimal,并设置对应精度
  27. return 'decimal:2';
  28. case 'float':
  29. case 'double':
  30. case 'real':
  31. return 'float';
  32. case 'bool':
  33. case 'boolean':
  34. return 'boolean';
  35. default:
  36. return null;
  37. }
  38. }
  39. protected function formatPropertyType(string $type, ?string $cast): ?string
  40. {
  41. if (! isset($cast)) {
  42. $cast = $this->formatDatabaseType($type) ?? 'string';
  43. }
  44. switch ($cast) {
  45. case 'integer':
  46. return 'int';
  47. case 'date':
  48. case 'datetime':
  49. return '\Carbon\Carbon';
  50. case 'json':
  51. return 'array';
  52. }
  53. if (Str::startsWith($cast, 'decimal')) {
  54. // 如果 cast 为 decimal,则 @property 改为 string
  55. return 'string';
  56. }
  57. return $cast;
  58. }
  59. }

配置映射关系 dependencies.php

  1. <?php
  2. return [
  3. Hyperf\Database\Commands\Ast\ModelUpdateVisitor::class => App\Kernel\Visitor\ModelUpdateVisitor::class,
  4. ];

重新执行 gen:model 后,对应模型如下:

  1. <?php
  2. declare (strict_types=1);
  3. namespace App\Model;
  4. /**
  5. * @property int $id
  6. * @property int $count
  7. * @property string $float_num
  8. * @property string $str
  9. * @property string $json
  10. * @property \Carbon\Carbon $created_at
  11. * @property \Carbon\Carbon $updated_at
  12. */
  13. class UserExt extends Model
  14. {
  15. /**
  16. * The table associated with the model.
  17. *
  18. * @var string
  19. */
  20. protected $table = 'user_ext';
  21. /**
  22. * The attributes that are mass assignable.
  23. *
  24. * @var array
  25. */
  26. protected $fillable = ['id', 'count', 'float_num', 'str', 'json', 'created_at', 'updated_at'];
  27. /**
  28. * The attributes that should be cast to native types.
  29. *
  30. * @var array
  31. */
  32. protected $casts = ['id' => 'integer', 'count' => 'integer', 'float_num' => 'decimal:2', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
  33. }