rancoud/model

4.1.7 2024-09-02 12:03 UTC

README

Packagist PHP Version Support Packagist Version Packagist Downloads Composer dependencies Test workflow Codecov

数据操作之间的抽象模型,以改善代码和数据库之间的数据操作。

依赖项

数据库包: https://github.com/rancoud/Database

安装

composer require rancoud/model

如何使用它?

将 Rancoud\Model\Model 扩展到您的类。
您必须实现两个抽象方法 setFields 和 setTable。

  • setFields 用于设置表中的字段
  • setTable 用于设置数据库中的表
class User extends Model
{
    protected function setFields(): void
    {
        $this->fields = [
            'id'       => new Field('int', ['not_null', 'unsigned', 'pk']),
            'nickname' => new Field('varchar', ['max:255', 'not_null'])
        ];
    }

    protected function setTable(): void
    {
        $this->table = 'user';
    }
}

什么是字段?

字段表示表中的一个字段。
它有 3 个参数

  1. 字段类型
  2. 规则
  3. 默认值

字段类型

它支持以下字段类型

  • int
  • float
  • char
  • varchar
  • text
  • date
  • datetime
  • time
  • timestamp
  • year
  • enum:x,y,z (x,y,z 代表每个可能值)

规则

  • pk : 主键
  • fk : 外键
  • unsigned : 仅正数
  • email : 检查是否是有效的电子邮件
  • not_null : 不能为空
  • max:x : 最大大小 (x 是大小)
  • min:x : 最小大小 (x 是大小)
  • range:x,y : 最小大小 + 最大大小 (x 是最小大小,y 是最大大小)

自定义规则

class MyRule extends CustomRule
{
    public function applyRule($value)
    {
        if ($value === 'azerty') {
            throw new FieldException('invalid azerty value');
        }

        return $value;
    }
}

默认值

当值未设置时,可以使用以下参数进行设置

辅助函数

它有分页、创建、读取、更新和删除的方法。

// $database is an instance of Rancoud\Database\Database
$user = new User($database);

$newId = $user->create(['nickname' => 'rancoud']);

$row = $user->one($newId);
// you will have an array representing data in database with correct types
// here : ['id' => 1, 'nickname' => 'rancoud'];
$rows = $user->all();
// here it's all rows in table : [ ['id' => 1, 'nickname' => 'rancoud'] ] 

$user->update(['nickname' => 'rancoud2'], $newId);

$user->delete($newId);

Model::all() 接受一个包含一些键的数组,这些键会触发特定操作

// $database is an instance of Rancoud\Database\Database
$user = new User($database);

// 50 rows using LIMIT 50 OFFSET 50
$rows = $user->all(['page' => 1]);
// 10 rows using LIMIT 10 OFFSET 10
$rows = $user->all(['count' => 10, 'page' => 1]);

// count rows in table
$count = $user->all(['rows_count' => 1]);

// return all rows with no limit 
$count = $user->all(['no_limit' => 1]);

// change order by
$count = $user->all(['order' => 'nickname']);
// change order by and order
$count = $user->all(['order' => 'nickname|desc']);
// multiple change order by and order
$count = $user->all(['order' => 'nickname|desc,id|asc']);

您可以使用覆盖函数更改 Model::all() 中输出的值

  • getSqlAllSelectAndFillSqlParams(params: array)
  • getSqlAllJoinAndFillSqlParams(params: array)
  • getSqlAllWhereAndFillSqlParams(params: array)

回调函数

您可以在创建、更新和删除之前和之后添加回调函数。

$model->addBeforeCreate('a', function($sql, $params){
    // for modifying sql and params use this return otherwise don't
    return [$sql, $params];
});

$model->addAfterCreate('a', function($newId, $params){
    // for modifying params use this return otherwise don't
    return $params;
});

$model->addBeforeUpdate('a', function($sql, $params){
    // for modifying sql and params use this return otherwise don't
    return [$sql, $params];
});

$model->addAfterUpdate('a', function($params){
    // for modifying params use this return otherwise don't
    return $params;
});

$model->addBeforeDelete('a', function($sql, $params){
    // for modifying sql and params use this return otherwise don't
    return [$sql, $params];
});

$model->addAfterDelete('a', function($params){
    // for modifying params use this return otherwise don't
    return $params;
});

您可以使用 JsonOutput trait 为模型添加 JSON 格式。

字段构造函数

设置

必需

可选

字段方法

  • isPrimaryKey(): bool
  • isForeignKey(): bool
  • isNotNull(): bool
  • getDefault(): mixed
  • formatValue(value: mixed): ?mixed

模型构造函数

设置

必需

模型方法

通用命令

  • all(params: array, [validFields: array = []]): array|bool|int
  • one(id: mixed, [...ids: mixed = []]): array
  • create(args: array): bool|int
  • update(args: array, id: mixed, [...ids: mixed = []]): void
  • delete(id: mixed, [...ids: mixed = []]): void
  • getLastInsertId(): ?int

数据库错误

  • getDatabaseErrors(): ?array
  • getDatabaseLastError(): ?array

回调函数

添加

  • addBeforeCreate(name: string, callback: mixed): void
  • addAfterCreate(name: string, callback: mixed): void
  • addBeforeUpdate(name: string, callback: mixed): void
  • addAfterUpdate(name: string, callback: mixed): void
  • addBeforeDelete(name: string, callback: mixed): void
  • addAfterDelete(name: string, callback: mixed): void

删除

  • removeBeforeCreate(name: string): void
  • removeAfterCreate(name: string): void
  • removeBeforeUpdate(name: string): void
  • removeAfterUpdate(name: string): void
  • removeBeforeDelete(name: string): void
  • removeAfterDelete(name: string): void

静态辅助方法

  • getCountPerPage(args: array): int
  • getLimitOffsetCount(args: array): array
  • getOrderByOrderField(args: array, [validFields: array = []]): array
  • getPageNumberForHuman(args: array): int
  • getPageNumberForSql(args: array): int
  • hasInvalidPrimaryKey(value: int): bool
  • hasLimit(args: array): bool
  • implodeOrder(orders: array): string
  • isRowsCount(args: array): bool
  • isValidFieldForOrderBy(field: string, [validFields: array = []]): bool

如何开发

docker compose build && docker compose run lib composer ci 启动测试