prohalexey/the-choice

2.0.0 2020-04-03 13:49 UTC

This package is auto-updated.

Last update: 2024-09-29 04:49:49 UTC


README

Build Status GitHub license

PHP上的“业务规则引擎”

此库允许您简化编写业务流程的规则,例如

  • 复杂的折扣计算
  • 向您的客户发放奖金
  • 解决用户权限

如果您反复更改代码中的某些条件,这可能对您很有用。它允许您将这些条件移动到配置源。您甚至可以创建一个可以编辑配置的Web界面。您可以使用JSON或YAML格式编写规则,并将它们存储到文件或数据库中。配置可以被序列化和缓存。

安装

composer require prohalexey/the-choice

示例

JSON配置

{
  "node": "condition",
  "if": {
    "node": "collection",
    "type": "and",
    "elements": [
      {
        "node": "context",
        "context": "withdrawalCount",
        "operator": "equal",
        "value": 0
      },
      {
        "node": "context",
        "context": "inGroup",
        "operator": "arrayContain",
        "value": [
          "testgroup",
          "testgroup2"
        ]
      }
    ]
  },
  "then": {
    "node": "context",
    "description": "Giving 10% of deposit's sum as discount for the next order",
    "context": "getDepositSum",
    "modifiers": [
        "$context * 0.1"
    ],
    "params": {
        "discountType": "VIP client"
    }
  },
  "else": {
    "node": "value",
    "description": "Giving 5% for the next order",
    "value": "5"
  }
}

相同内容但以YAML配置形式

node: condition
if:
  node: collection
  type: and
  elements:
  - node: context
    context: withdrawalCount
    operator: equal
    value: 0
  - node: context
    context: inGroup
    operator: arrayContain
    value:
      - testgroup
      - testgroup2
then:
  node: context
  context: getDepositSum
  description: "Giving 10% of deposit's sum as discount for the next order"
  modifiers: 
    - "$context * 0.1"
  params:
    discountType: "VIP client"
else:
  node: value
  description: "Giving 5% for the next order"
  value: 5

在PHP中使用

use TheChoice\Container;

// Passing contexts to the PSR-11 compatible container
$container = new Container([
    'visitCount' => VisitCount::class,
    'hasVipStatus' => HasVipStatus::class,
    'inGroup' => InGroup::class,
    'withdrawalCount' => WithdrawalCount::class,
    'depositCount' => DepositCount::class,
    'utmSource' => UtmSource::class,
    'contextWithParams' => ContextWithParams::class,
    'action1' => Action1::class,
    'action2' => Action2::class,
    'actionReturnInt' => ActionReturnInt::class,
    'actionWithParams' => ActionWithParams::class,
]);

// Creating a parser 
$parser = $container->get(JsonBuilder::class);

// Load rules from a file or other sources
$rules = $parser->parseFile('Json/testOneNodeWithRuleGreaterThan.json');

// Loading processor
$resolver = $container->get(ProcessorResolverInterface::class);
$processor = $resolver->resolve($rules);

// Process the rules
$result = $processor->process($rules);

核心功能

节点类型

每个节点都有一个“node”属性,用于描述节点的类型。此外,每个节点还有一个“description”属性,可以用于存储用于UI的描述。

根节点

这是规则树的根节点。它具有状态并存储执行结果。

#### 节点属性 storage - 简单变量容器。

rules - 此属性包含将被处理的第一节点。实际上,即使您省略此节点,它也将自动创建。

#### 示例

node: root
description: "Discount settings"
nodes: 
  node: value
  value: 5

这是一个简单的节点,仅返回一些值。

#### 节点属性 value - 简单值

#### 示例

node: value
description: "Giving 5% for the next order"
value: 5

值可以是数组、字符串或数字。

上下文

这是与某些可调用对象关联的节点,并作为可调用对象的执行结果返回一些值。此节点可以更改存储在“根”节点中的全局状态。

#### 节点属性 break - 是一个特殊属性,可以在执行此节点后停止规则处理器。目前唯一允许的值是“立即”停止规则执行,并将上下文结果作为最终结果返回。

contextName - 用于计算的上下文名称。

modifiers - 修饰符数组。

operator - 用于计算或比较的运算符。

params - 要在上下文中设置的参数数组。

priority - 优先级节点。如果在此集合中使用此节点,则集合中的元素将根据此值排序。

value - $context 变量的默认值;

#### 示例

node: context
context: getDepositSum
description: "Giving 10% of deposit's sum as discount for the next order"
modifiers: 
  - "$context * 0.1"
params:
  discountType: "VIP client"
priority: 5

如果此“可调用”是对象,则可以将参数设置为“可调用”。在执行规则之前,将通过设置器或公共属性设置参数。

您可以使用修饰符来修改上下文返回的值。使用预定义变量 $context。有关计算的更多信息,请阅读此 https://github.com/chriskonnertz/string-calc

node: context
context: withdrawalCount
operator: equal
value: 0

结果将存储在存储中或返回给“根”节点。

您可以使用内置运算符来测试上下文节点返回的值与某些值。

运算符必须返回布尔值

这些内置运算符可以使用,或者您可以注册新的自定义运算符并将它们添加到容器中。

ArrayContain
ArrayNotContain
Equal
GreaterThan
GreaterThanOrEqual
LowerThan
LowerThanOrEqual
NotEqual
NumericInRange
StringContain
StringNotContain

集合

集合是包含其他节点的节点。

#### 节点属性

type - 可用的集合类型有 AND 和 OR。

nodes - 节点数组。

priority - 优先级节点。如果在此集合中使用此节点,则集合中的元素将根据此值排序。

PRIORITY 属性用于此节点位于另一个集合(例如集合的集合)中时。

#### 示例

node: collection
  type: and
  elements:
  - node: context
    context: withdrawalCount
    operator: equal
    value: 0
  - node: context
    context: inGroup
    operator: arrayContain
    value:
      - testgroup
      - testgroup2

此节点从节点期望布尔值,并根据集合类型返回值。

条件

用于测试某些条件的条件节点。

if - 期望从内部节点获取布尔值。

then - 包含另一个 IF 节点的其他节点。如果 IF 结果为 TRUE,则执行

else - 包含另一个 IF 节点的其他节点。如果 IF 结果为 FALSE,则执行

有什么问题吗?

请参阅测试和容器以获取更多详细信息。