skrip42/node-processor

节点处理器

v1.0 2020-01-28 08:52 UTC

This package is auto-updated.

Last update: 2024-09-28 21:06:09 UTC


README

描述

Node Process是一个在PHP之上运行的小型程序,类似于过程式程序。

安装

composer require skrip42/node-processor

文档

节点处理

节点处理是一个在PHP之上运行的小型程序,类似于过程式程序。进程由节点及其之间的连接以及这些节点的状态组成。一个重要的后果是:在任何时候,进程都可以停止,保存当前状态,并从相同点继续执行。进程可以使用PHP、序列化和反序列化动态创建。

基本使用

添加

use Skrip42\NodeProcessor\Process;

到您的文件顶部。您还可以添加您打算使用的所有节点

use Skrip42\NodeProcessor\Node\Other\ValueNode;
use Skrip42\NodeProcessor\Node\Logical\CompareNode;
创建进程

本节旨在了解进程,创建进程的推荐方法是进程构建器

$process = new Process; //create new process;

//create all necessary nodes:
// as syntax: process->createNode($nodeClassName, ...$values) : NodeAbstract
$valNode1 = $process->createNode(ValueNode::class, 1); //you can pass start parameters to the node if required 
$valNode2 = $process->createNode(ValueNode::class, 5);
$compareNode = $process->createNode(ValueNode::class);
//You do not need to create a start and end node, they are already included in the process

//link nodes:
// as syntax: process->linkNode($outputNodeName, $outputNode, $inputNodeName, $inputNode)
$process->linkNode('out1', $process->getBeginNode(), 'emit', $valNode1); // you can get begin and end node
                                                                        // from getBeginNode and getEndNode methods
$process->linkNode('out2', $process->getBeginNode(), 'emit', $valNode2);
$process->linkNode('out', $valNode1, 'in1', $compareNode);
$process->linkNode('out', $valNode2, 'in2', $compareNode);
$process->linkNode('more', $compareNode, 'more', $process->getEndNode()); // end node has dynamically input name
$process->linkNode('less', $compareNode, 'less', $process->getEndNode());
//You can always leave output nodes empty; can input be left blank determined by node policy

生成的进程可以以图形方式表示

                        ┌───────────────┐         
                  ┌─emit┤ ValueNode = 1 ├out─┐    ┌─────────────┐            ┌─────────┐
┌───────────┐     │     └───────────────┘    └─in1┤             ├more────more┤         │
│           ├out1─┘                               │             │            │ EndNode │
│ BeginNode │                                     │ CompareNode ├less────less┤         │
│           ├out2─┐                               │             │            └─────────┘
└───────────┘     │     ┌───────────────┐    ┌─in2┤             ├equal─X
                  └─emit┤ ValueNode = 5 ├out─┘    └─────────────┘
                        └───────────────┘         

大多数节点都有一个或多个输入和输出。标准节点的输入和输出名称可以在文档中找到

运行进程和调试

为了启动进程

$result = $process->run(); // running process
$state = $process->getState(); // you also can get current process state for debug you script

您将得到以下形式的数组

[
    'status' => currentProcessStatus,
    'output' => [ .. array of end node inputs .. ]
    'requests' =>  [ .. array of requests .. ]
]

状态是表示进程当前状态的数字

  • Process::STATUS_READY - 准备运行
  • Process::STATUS_RUNNING - 运行中
  • Process::STATUS_ERROR - 完成出错
  • Process::STATUS_WAIT_RESPONSE - 等待响应(见请求/响应
  • Process::STATUS_COMPLETE - 完成

输出是EndNode输入的数组。输入名称映射到数组键。

请求是请求的数组(见请求/响应

$process->getState() - 返回进程当前状态,所有进程节点,所有节点的输入和输出。在节点标识符及其输入和输出名称之后,您可以查看节点启动次数,每个输入接收到的信号次数以及每个输出发射的信号次数

序列化/反序列化进程

您可以使用默认的PHP工具序列化和反序列化进程

$serialized = serialize($process);
$process = unserialize($serialized);

如果您不想序列化它们,则不应在节点中包含其他对象或将它们作为参数传递!

进程构建器

创建进程的一个更方便的方法是通过进程构建器。之前的进程可以创建如下

$process = Process::build(
    [
        'node' => [
            'vn1' => [ValueNode::class, 1],
            'vn2' => [ValueNode::class, 5],
            'cn' => [CompareNode::class],
        ],
        'link' => [
            ['out1', 'begin', 'emit', 'vn1'], //begin is the predefined start node name
            ['out2', 'begin', 'emit', 'vn2'],
            ['out', 'vn1', 'in1', 'cn'],
            ['out', 'vn2', 'in2', 'cn'],
            ['less', 'cn', 'less', 'end'], //end is the predefined end node name
            ['more', 'vn2', 'more', 'end'], 
        ]
    ]
);

使用构建器,您还可以参数化您的进程

$process = Process::build(
    [
        'node' => [
            'vn1' => [ValueNode::class, '{$val1}'], // template syntax: {$valueName}
            'vn2' => [ValueNode::class, '{$val2}'],
            'cn' => [CompareNode::class],
        ],
        'link' => [
            ['out1', 'begin', 'emit', 'vn1'], //begin is the predefined start node name
            ['out2', 'begin', 'emit', 'vn2'],
            ['out', 'vn1', 'in1', 'cn'],
            ['out', 'vn2', 'in2', 'cn'],
            ['less', 'cn', 'less', 'end'], //end is the predefined end node name
            ['more', 'vn2', 'more', 'end'], 
        ]
    ],
    [ //value list
        'val1' => 1,
        'val2' => 5
    ]
);

请求/响应

为了在提供的请求/响应系统中传达外部代码,某些节点可以向进程发送请求。然后进程将返回状态“等待响应”,因此将有一个如下形式的请求列表

[
    ['uniqIdOfRequest' => 'request data'],
    .......
]

您可以发送如下回答:

$process->setResponse('uniqIdOfRequest', 'response data');

然后进程将继续从发送请求的节点执行(从“setResponse”方法中的节点)

节点

节点是进程的基本构建块。大多数节点都有一个或多个输入和输出。如果输入为“必需”,则节点在没有接收到此输入的情况下无法运行。输入和输出可以动态声明(作为模式或自由)。输出可以有默认值。输入和输出存储它们的值。输入和输出有一个开始计数器。节点在接收到所有必需输入后运行。节点在接收到任何输入时运行(如果所有必需输入都有值)。节点可以从eval()方法强制运行(不推荐)。节点可以发出请求并接收响应。

该模块提供了一些基本节点

通用节点

管理节点

开始节点
描述

起始节点,进程启动时执行

参数
  • 混合值 = true
图形界面
 ┌─────────────┐
 │             ├─ out1
 │             │
 │             │
 │             ├─ out2
 │  BeginNode  │
 │             │
 │             ├─ ...
 │             │
 │             │
 │             ├─ out$n
 └─────────────┘
输入

输出
  • 一个或多个输出,按照模式 out{数字}输出
请求

逻辑

从所有输出发出 $value

结束节点
描述

结束节点,收集进程的结果

参数

图形界面
      ┌───────────────┐
in1  ─┤               │
      │               │
in2  ─┤               │
      │    EndNode    │
...  ─┤               │
      │               │
in$n ─┤               │
      └───────────────┘
输入
  • 任何名称的任何值的某个数量
输出

请求

逻辑

收集所有输入值并将其映射到进程结果数组。输入可以有任何名称,这些名称映射到结果数组的键。

分割节点
描述

分支进程处理

参数

图形界面
     ┌───────────────┐
     │               ├─ out1
     │               │
     │               ├─ out2
in  ─┤  SplitterNode │
     │               ├─ ...
     │               │
     │               ├─ out$n
     └───────────────┘
输入
  • 输入 - 必需的任何类型
输出
  • 任何数量的值,名称类似于模式:out{数字}
请求

逻辑

将输入值发出到所有输出 out1 = out2 = ... = out$n = in

单节点
描述

简化输入信号

参数

图形界面
       ┌───────────────┐
in    ─┤               │
       │   SingleNode  ├─ out
reset ─┤               │
       └───────────────┘
输入
  • 输入 - 必需的任何类型
  • 重置 - 任何值以重置输入锁
输出
  • 输出 - 等于输入的第一个值
请求

逻辑

仅对第一次输入信号发出输出信号

等待节点
描述

等待发出信号以继续

参数

图形界面
      ┌───────────────┐
in   ─┤               │
      │  WaitingNode  ├─ out
emit ─┤               │
      └───────────────┘
输入
  • 输入 - 必需的任何类型
  • 重置 - 必需的布尔值
输出
  • 输出 - 等于输入
请求

逻辑

仅当 'emit' 信号 = true 时发出输出

触发节点
描述

当接收到输入信号时发出附加信号

参数

图形界面
      ┌───────────────┐
      │               ├─ before
      │               │
in   ─┤  TriggerNode  ├─ out
      │               │
      │               ├─ after
      └───────────────┘
输入
  • 输入 - 必需的任何类型
输出
  • 在 ... 之前 - true
  • 输出 - 等于输入
  • 在 ... 之后 - true
请求

逻辑

当接收到输入时发出 'before'=true 输出,在输出发出之前发出 'out' = 'in',当接收到输入并在输出发出之后发出 'after'=true 输出

迭代节点
描述

迭代数组以接收每个 'emit' 信号

参数

图形界面
        ┌───────────────┐
array  ─┤               ├─ out
        │               │
emit   ─┤  IterateNode  ├─ complete
        │               │
reset  ─┤               ├─ count
        └───────────────┘
输入
  • 数组 - 必需的数组
  • 发出 - 必需的任何类型
  • 重置 - 重置控制
输出
  • 输出 - 任何类型值(为 'array' 的每个元素发出)
  • 完成 - true(当数组结束时发出)
  • 计数 - 'array' 元素的数量(在接收到 'array' 信号时发出)
请求

逻辑

当接收到 'array' 信号时发出 'count' = count(array) 信号,对于每个接收到的 'emit' 信号发出 'out' = array[$n],当数组结束时发出 'complete' = true

暂停节点
描述

停止当前线程,直到收到响应

参数

图形界面
      ┌───────────────┐
      │               │
 in  ─┤   PauseNode   ├─ out
      │               │
      └───────────────┘
输入
  • 输入 - 必需的任何类型
输出
  • 输出 - 等于输入的任何类型值
请求
  • '暂停':等待任何响应
逻辑

停止当前线程,直到收到响应,然后将输入转发到输出

重复节点
描述

重复'输入'指定次数

参数

$value - 重复次数的计数

图形界面
      ┌───────────────┐
      │               ├─ out
 in  ─┤   RepeatNode  │
      │               ├─ complete
      └───────────────┘
输入
  • 输入 - 必需的任何类型
输出
  • 输出 - 等于输入的任何类型值
  • 完成 - true(在重复结束时发出)
请求

逻辑

将输入转发到输出,并重复'$value'次。当重复次数结束时,发出完成=true

子进程节点
描述

在node中运行子进程(Process的另一个实例)

参数

$subprocessScheme类似于进程构建器

图形界面
       ┌─────────────────────┐
 in1  ─┤                     ├─ out1
       │                     │
 in2  ─┤                     ├─ out2
       │    SubProcessNode   │
 ...  ─┤                     ├─ ...
       │                     │
 in$n ─┤                     ├─ ount$n
       └─────────────────────┘
输入

根据方案将输入映射到方案参数

输出

根据方案将子进程输出映射到节点输出

请求

从子进程中转发请求,将响应转发到子进程中

逻辑

在SubProcessNode内部运行子进程(Process的实例),将输入映射到子进程方案参数,并将子进程输出映射到当前输出。转发子进程请求和响应。当子进程状态为Process::STATUS_COMPLETE时,发出所有输出

多子进程节点
描述

在node中运行子进程的指定分叉(Process的另一个实例)

参数

$subprocessScheme类似于进程构建器

图形界面
       ┌─────────────────────┐
 in1  ─┤                     ├─ out1
       │                     │
 in2  ─┤                     ├─ out2
       │ MultiSubProcessNode │
 ...  ─┤                     ├─ ...
       │                     │
 in$n ─┤                     ├─ ount$n
       └─────────────────────┘
输入

根据方案将简单输入映射到方案参数,将数组输入的每个元素映射到适当数量的子进程

输出

根据方案将收集到的子进程输出(作为数组)

请求

从子进程中转发请求,将响应转发到子进程中

逻辑

为最大输入值数组的每个元素运行子进程实例。将所有子进程输出收集为适当的数组,并将其映射到输出。转发所有子进程请求到节点请求,将所有节点响应转发到子进程响应。当所有子进程状态为Process::STATUS_COMPLETE时,发出所有输出

逻辑节点

与节点
描述

逻辑与节点

参数

图形界面
       ┌───────────────┐
 in1  ─┤               │
       │               ├─ out
 in2  ─┤               │
       │    AndNode    │
 ...  ─┤               │
       │               ├─ iout
 in$n ─┤               │
       └───────────────┘
输入
  • 某些输入名称类似于模式'in{$number}' - 必须是布尔值
输出
  • out - 所有输入的逻辑与
  • iout - out的逆
请求

逻辑

'out' = 'in1' && 'in2' && ... && 'in$n' 'iout' = !'out'

非节点
描述

逻辑非节点

参数

图形界面
      ┌───────────────┐
      │               │
 in  ─┤   CountNode   ├─ out
      │               │
      └───────────────┘
输入
  • in - 必须是布尔值
输出
  • out - 输入的逻辑非
请求

逻辑

'out' = !'in'

或节点
描述

逻辑或节点

参数

图形界面
       ┌───────────────┐
 in1  ─┤               │
       │               ├─ out
 in2  ─┤               │
       │     OrNode    │
 ...  ─┤               │
       │               ├─ iout
 in$n ─┤               │
       └───────────────┘
输入
  • 某些输入名称类似于模式'in{$number}' - 必须是布尔值
输出
  • out - 所有输入的逻辑与
  • iout - out的逆
请求

逻辑

'out' = 'in1' || 'in2' || ... || 'in$n'

异或节点
描述

逻辑异或节点

参数

图形界面
       ┌───────────────┐
 in1  ─┤               │
       │               ├─ out
 in2  ─┤               │
       │    XorNode    │
 ...  ─┤               │
       │               ├─ iout
 in$n ─┤               │
       └───────────────┘
输入
  • 某些输入名称类似于模式'in{$number}' - 必须是布尔值
输出
  • out - 所有输入的逻辑异或
  • iout - out的逆
请求

逻辑

out = (in1 || in2 || .. || in$n) && !(in1 && in2) && !(in2 && in3) && !(in1 && in3) ... 只有一个值必须是true iout = !out

比较节点
描述

逻辑异或节点

参数

图形界面
       ┌───────────────┐
       │               ├─ more
 in1  ─┤               │
       │               │
       │  CompareNode  ├─ less
       │               │
 in2  ─┤               │
       │               ├─ equal
       └───────────────┘
输入
  • in1 - 必须有一些比较值
  • in2 - 必须有一些比较值
输出
  • more - 当in1 > in2时为true
  • less - 当in1 < in2时为true
  • equal - 当in1 == in2时为true
请求

逻辑

more = in1 > in2 less = in1 < in2 equal = in1 == in2

算术节点

除法节点
描述

算术除法节点

参数

图形界面
       ┌───────────────┐
 in1  ─┤               │
       │               │
 in2  ─┤               │
       │   DivideNode  ├─ out
 ...  ─┤               │
       │               │
 in$n ─┤               │
       └───────────────┘
输入
  • 某些输入名称类似于模式'in{$number}' - 必须是数字
输出
  • out - 将in1除以所有in$n输入
请求

逻辑

out = in1 / in2 / .. / in$n

取模节点
描述

算术取模节点

参数

图形界面
       ┌───────────────┐
 in1  ─┤               │
       │               │
 in2  ─┤               │
       │    ModNode    ├─ out
 ...  ─┤               │
       │               │
 in$n ─┤               │
       └───────────────┘
输入
  • 某些输入名称类似于模式'in{$number}' - 必须是数字
输出
  • out - 将in1除以所有in$n输入的模
请求

逻辑

out = in1 % in2 % .. % in$n

乘法节点
描述

算术乘法节点

参数

图形界面
       ┌──────────────┐
 in1  ─┤              │
       │              │
 in2  ─┤              │
       │ MultiplyNode ├─ out
 ...  ─┤              │
       │              │
 in$n ─┤              │
       └──────────────┘
输入
  • 某些输入名称类似于模式'in{$number}' - 必须是数字
输出
  • out - 所有in$n输入的乘积
请求

逻辑

out = in1 * in2 * .. * in$n

减法节点
描述

算术减法节点

参数

图形界面
       ┌───────────────┐
 in1  ─┤               │
       │               │
 in2  ─┤               │
       │ SubstractNode ├─ out
 ...  ─┤               │
       │               │
 in$n ─┤               │
       └───────────────┘
输入
  • 某些输入名称类似于模式'in{$number}' - 必须是数字
输出
  • out - 从in1减去所有in$n输入
请求

逻辑

out = in1 - in2 - .. - in$n

加法节点
描述

算术加法节点

参数

图形界面
       ┌───────────────┐
 in1  ─┤               │
       │               │
 in2  ─┤               │
       │    SumNode    ├─ out
 ...  ─┤               │
       │               │
 in$n ─┤               │
       └───────────────┘
输入
  • 某些输入名称类似于模式'in{$number}' - 必须是数字
输出
  • out - 所有输入的和
请求

逻辑

out = in1 + in2 + .. + in$n

字符串节点

连接节点
描述

字符串连接节点

参数

图形界面
       ┌───────────────┐
 in1  ─┤               │
       │               │
 in2  ─┤               │
       │   ConcatNode  ├─ out
 ...  ─┤               │
       │               │
 in$n ─┤               │
       └───────────────┘
输入
  • 某些输入名称类似于模式'in{$number}' - 必须是字符串
输出
  • out - 所有输入的连接
请求

逻辑

'out' = in1 . in2 . ... . in$n

匹配节点
描述

字符串匹配节点

参数

$pattern - 匹配的正则表达式字符串

图形界面
      ┌───────────────┐
      │               ├─ out
 in  ─┤   MatchNode   │
      │               ├─ iout
      └───────────────┘
输入
  • in - 必须是字符串
输出
  • out - 如果匹配成功则为true
  • iout - out的逆
请求

逻辑

如果'in'匹配模式,则发出'out'。如果'in'不匹配模式,则发出'iout'

替换节点
描述

替换字符串或字符串部分

参数

$pattern - 匹配的正则表达式字符串 $replacement - 替换的字符串

图形界面
      ┌───────────────┐
      │               │
 in  ─┤  ReplaceNode  ├─ out
      │               │
      └───────────────┘
输入
  • in - 必须是字符串
输出
  • out - 结果字符串
请求

逻辑

equal preg_replace($pattern, $replacement, 'in');

数组节点

收集节点
描述

将输入信号收集到数组中

参数

图形界面
       ┌───────────────┐
 in   ─┤               │
       │  CollectNode  ├─ out
 emit ─┤               │
       └───────────────┘
输入
  • in - 必须是混合类型
  • emit - 必须是true
输出
  • out - 输入值的数组
请求

逻辑

收集所有'输入'信号到数组,当接收到'发射'信号时,发射此数组

CombineNode
描述

将所有输入收集到单个数组中

参数

图形界面
       ┌───────────────┐
 in1  ─┤               │
       │               │
 in2  ─┤               │
       │  CombineNode  ├─ out
 ...  ─┤               │
       │               │
 in$n ─┤               │
       └───────────────┘
输入
  • 某些输入名称符合模式'input{$number}' - 必需的混合
输出
  • out - 输入值数组
请求

逻辑

将所有输入组合到数组中,如['in1' => $valueOfIn1, 'in2' => $valueOfIn2, ...]

CountNode
描述

将输入信号收集到数组中

参数

图形界面
        ┌───────────────┐
        │               │
 array ─┤   CountNode   ├─ out
        │               │
        └───────────────┘
输入
  • 数组 - 必需的数组
输出
  • out - 数组值的计数
请求

逻辑

发射'array'元素的计数

EachNode
描述

为输入数组的每个元素发射输出

参数

图形界面
        ┌──────────────┐
        │              ├─ out
        │              │
 array ─┤   EachNode   ├─ key
        │              │
        │              ├─ complete
        └──────────────┘
输入
  • 数组 - 必需的数组
输出
  • out - 'array'的单个值
  • key - 'array'的单个键
  • complete - 当数组结束时为true
请求

逻辑

为每个'array'元素发射'out'和'key',当数组结束时发射'complete'

ExtractNode
描述

通过键从数组中提取单个值

参数

$key - 键

图形界面
        ┌───────────────┐
        │               │
 array ─┤  ExtractNode  ├─ out
        │               │
        └───────────────┘
输入
  • 数组 - 必需的数组
输出
  • out - 发射数组的单个值
请求

逻辑

发射array[$key]

其他节点

计数器节点
描述

计算输入信号的计数

参数

图形界面
      ┌───────────────┐
      │               │
 in  ─┤  CounterNode  ├─ out
      │               │
      └───────────────┘
输入
  • in - 必须是混合类型
输出
  • out - 发射输入信号的计数
请求

逻辑

计算输入信号计数,每次接收到'in'时发射'out'

转储节点
描述

输出输入值

参数

图形界面
      ┌───────────────┐
      │               │
 in  ─┤    DumpNode   ├─ out
      │               │
      └───────────────┘
输入
  • in - 必须是混合类型
输出
  • out - 等于'in'
请求

逻辑

将输入值转发到输出。如果可用,调用dump('in')。如果以命令行模式运行,调用var_export。如果以fpm模式运行,调用var_dump。

随机节点
描述

随机值发射器

参数

$min - 随机值的最小值 $max - 随机值的最大值

图形界面
       ┌───────────────┐
       │               │
 emit ─┤    RandNode   ├─ out
       │               │
       └───────────────┘
输入
  • emit - 必需的混合
输出
  • out - 随机数值
请求

逻辑

当接收到'emit'时,将随机($min=0, $max=1)值发射到'out'

范围节点
描述

范围生成器

参数

$start - 范围的起始值 $end - 范围的结束值 $step - 范围的步长

图形界面
       ┌───────────────┐
       │               │
 emit ─┤    RageNode   ├─ out
       │               │
       └───────────────┘
输入
  • emit - 必需的混合
输出
  • out - 数组
请求

逻辑

等于range($start, $end, $step=1),当接收到'emit'时发射数组

值节点
描述

值发射器

参数

$value - 发射的值

图形界面
       ┌───────────────┐
       │               │
 emit ─┤   ValueNode   ├─ out
       │               │
       └───────────────┘
输入
  • emit - 必需的混合
输出
  • out - 值
请求

逻辑

当接收到'out'时发射值

创建用户节点

要创建用户节点类型,创建一个从NodeAbstract扩展的类,并定义公共eval()方法

输入/输出定义

输入和输出策略在静态属性$scheme中声明

static propery $scheme = [
    'input' => [                //input declaration
        'optionalInput' => [       //optional input named as 'optionalInput'
        ],
        'requiredInput' => [       //required input named as 'requiredInput'
            'required' => true,    //set 'required' => true to make input required
        ]
    ],
    'user_input' => [           //dynamic input declarated
        'pattern' => '~in\d+~', //pattern for available input names
        'property' => [
            'required' => true  //also can be required
        ]
    ],
    'output' => [                       //output declaration
        'outputWithDefaultData' => [    //output named as 'outputWithDefaultData'
            'data' => 'default data'        //define 'data' property to define default data
        ],
        'outputWithoutDefaultData' => [ //output named as 'outputWithoutDefaultData'
        ]
    ],
    'user_output' => [  //dynamic output declarated
    ],                  //if pattern property is null, all names available
]

只有当所有必需的输入都接收到时,才发射输出

读取输入/输出,发射信号

您可以通过以下方式访问输入和输出

$value = $this->input['inputName']['data']; //get value from 'inputName' input
$this->output['outputName']['data'] = $value; //set value to 'outputName' output (not emitted)

要发射输出,请打印

$this->emit('outputName');
//or you can set value and output:
$this->emit('ouputName', $sumeValue);

请求/响应处理

您可以从节点发射请求

$this->sendRequest($data, $id=null); //if $id == null $id get automaticaly uniq identifier

要处理节点中的响应,扩展setResponse方法

public function setResponse($id, $data)
{
    ....do somethind
}