ngmy/规范

这是一个帮助在PHP中实现规范模式的库。它提供了内存验证、内存和ORM选择以及规范组合。

v0.4.0 2022-08-04 13:26 UTC

This package is auto-updated.

Last update: 2024-09-04 22:24:41 UTC


README

英文 | 日语

PHP规范

test coverage

这是一个帮助在PHP中实现规范模式的库。
它提供了内存验证、内存和ORM选择以及规范组合。

安装

composer require ngmy/specification

使用

规范创建和内存验证与选择

通过从AbstractSpecification类继承来创建您的规范类。

然后实现isSatisfiedBy方法。
在这个方法中,编写满足规范的标准。

此外,使用@extends注解来编写isSatisfiedBy方法期望的对象类型,以方便静态分析。

<?php

declare(strict_types=1);

use Ngmy\Specification\AbstractSpecification;

/**
 * Popular user specification.
 *
 * @extends AbstractSpecification<User>
 */
class PopularUserSpecification extends AbstractSpecification
{
    /**
     * {@inheritdoc}
     */
    public function isSatisfiedBy($candidate): bool
    {
        return $candidate->getVotes() > 100;
    }
}

通过用要验证的对象调用isSatisfiedBy方法,您可以验证该对象是否满足规范。

$spec = new PopularUserSpecification();
$spec->isSatisfiedBy($user);

当然,它也可以用于选择。

$spec = new PopularUserSpecification();
$popularUsers = array_filter(function (User $users) use ($spec): void {
    return $spec->isSatisfiedBy($user);
}, $users);

ORM选择

Eloquent

实现applyToEloquent方法。
使用where方法等在这个方法中编写选择标准。

use Illuminate\Contracts\Database\Eloquent\Builder;

/**
 * {@inheritdoc}
 */
public function applyToEloquent(Builder $query): void
{
    $query->where('votes', '>', 100);
}

通过传递Eloquent构建器调用applyToEloquent方法,您可以向查询添加选择标准。

$query = User::query(); // User is your Eloquent model
$spec = new PopularUserSpecification();
$spec->applyToEloquent($query);
$popularUsers = $query->get();

Doctrine

实现applyToDoctrine方法。
使用andWhere方法等在这个方法中编写选择标准。

use Doctrine\ORM\QueryBuilder;
use Ngmy\Specification\Support\DoctrineUtils;

/**
 * {@inheritdoc}
 */
public function applyToDoctrine(QueryBuilder $queryBuilder): void
{
    $queryBuilder->andWhere($queryBuilder->expr()->gt(
        DoctrineUtils::getRootAliasedColumnName($queryBuilder, 'votes'),
        DoctrineUtils::createUniqueNamedParameter($this, $queryBuilder, 100),
    ));
}

通过传递查询构建器调用applyToDoctrine方法,您可以向查询添加选择标准。

/** @var \Doctrine\ORM\EntityManager $entityManager */
$queryBuilder = $entityManager->createQueryBuilder();
$queryBuilder->select('u')->from(User::class, 'u'); // User is your Doctrine entity
$spec = new PopularUserSpecification();
$spec->applyToDoctrine($queryBuilder);
$popularUsers = $queryBuilder->getQuery()->getResult();

组合

您可以使用AND、OR和NOT来组合规范。
在组合规范时,isSatisfiedByapplyToEloquentapplyToDoctrine方法中编写的标准也会组合。

AND

通过将另一个规范的实例传递给规范的and方法并调用它,您可以生成一个新的规范,它是两个规范之间的AND组合。

$spec1 = new Specification1();
$spec2 = new Specification2();
$spec3 = $spec1->and($spec2);

OR

通过将另一个规范的实例传递给规范的or方法并调用它,您可以生成一个新的规范,它是两个规范之间的OR组合。

$spec1 = new Specification1();
$spec2 = new Specification2();
$spec3 = $spec1->or($spec2);

NOT

通过调用规范的not方法,您可以生成一个新的规范,它是自身的不组合。

$spec1 = new Specification1();
$spec2 = $spec1->not();

使用示例

  • ngmy/php-specification-example
    • 该项目是使用PHP规范实现规范模式的代码示例。
      它遵循领域驱动设计方法,并包含规范和仓库组合的代码示例。
      它使用Eloquent和Doctrine作为ORM。

许可

PHP规范是开源软件,使用MIT许可