php 规则引擎,规则引擎RulerZ用法及实现原理(代码示例)

本文介绍了PHP规则引擎RulerZ的使用方法、实现原理和代码示例,包括安装、数据过滤、规则判断等功能。RulerZ是一个基于Composer的依赖包,支持数组和常见ORM的数据过滤,还支持Solr搜索引擎。文章详细阐述了从创建编译器到最终执行过滤操作的过程,涉及编译目标、抽象语法树和操作符解析。
摘要由CSDN通过智能技术生成

本篇文章给大家带来的内容是关于规则引擎RulerZ用法及实现原理(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

废话不多说,rulerz的官方地址是:https://github.com/K-Phoen/ru...

注意,本例中只拿普通数组做例子进行分析

1. 简介

RulerZ是一个用php实现的composer依赖包,目的是实现一个数据过滤规则引擎。RulerZ不仅支持数组过滤,也支持一些市面上常见的ORM,如Eloquent、Doctrine等,也支持Solr搜索引擎。

这是一个缺少中文官方文档的开源包,当然由于star数比较少,可能作者也觉得没必要。

2.安装

在你的项目composer.json所在目录下运行:composer require 'kphoen/rulerz'

3.使用 - 过滤

现有数组如下:$players = [

['pseudo' => 'Joe', 'fullname' => 'Joe la frite', 'gender' => 'M', 'points' => 2500],

['pseudo' => 'Moe', 'fullname' => 'Moe, from the bar!', 'gender' => 'M', 'points' => 1230],

['pseudo' => 'Alice', 'fullname' => 'Alice, from... you know.', 'gender' => 'F', 'points' => 9001],

];

初始化引擎:use RulerZ\Compiler\Compiler;

use RulerZ\Target;

use RulerZ\RulerZ;

// compiler

$compiler = Compiler::create();

// RulerZ engine

$rulerz = new RulerZ(

$compiler, [

new Target\Native\Native([ // 请注意,这里是添加目标编译器,处理数组类型的数据源时对应的是Native

'length' => 'strlen'

]),

]

);

创建一条规则:$rule = "gender = :gender and points > :min_points'

将参数和规则交给引擎分析。$parameters = [

'min_points' => 30,

'gender' => 'F',

];

$result = iterator_to_array(

$rulerz->filter($players, $rule, $parameters) // the parameters can be omitted if empty

);

// result 是一个过滤后的数组

array:1 [▼

0 => array:4 [▼

"pseudo" => "Alice"

"fullname" => "Alice, from... you know."

"gender" => "F"

"points" => 9001

]

]

4.使用 - 判断是否满足规则$rulerz->satisfies($player, $rule, $parameters);

// 返回布尔值,true表示满足

5.底层代码解读

下面,让我们看看从创建编译器开始,到最后出结果的过程中发生了什么。

1.Compiler::create();

这一步是实例化一个FileEvaluator类,这个类默认会将本地的系统临时目录当做下一步临时类文件读写所在目录,文件类里包含一个has()方法和一个write()方法。文件类如下:<?php

declare(strict_types=1);

namespace RulerZ\Compiler;

class NativeFilesystem implements Filesystem

{

public function has(string $filePath): bool

{

return file_exists($filePath);

}

public function write(string $filePath, string $content): void

{

file_put_contents($filePath, $content, LOCK_EX);

}

}

2.初始化RulerZ引擎,new RulerZ()

先看一下RulerZ的构建方法:public function __construct(Compiler $compiler, array $compilationTargets = [])

{

$this->compiler = $compiler;

foreach ($compilationTargets as $targetCompiler) {

$this->registerCompilationTarget($targetCompiler);

}

}

这里的第一个参数,就是刚刚的编译器类,第二个是目标编译器类(实际处理数据源的),因为我们选择的是数组,所以这里的目标编译器是Native,引擎会将这个目标编译类放到自己的属性$compilationTargets。public function registerCompilationTarget(CompilationTarget $compilationTarget): void

{

$this->compilationTargets[] = $compilationTarget;

}

3.运用filter或satisfies方法

这一点便是核心了。

以filter为例:public function filter($target, string $rule, array $parameters = [], array $executionContext = [])

{

$targetCompiler = $this->findTargetCompiler($target, CompilationTarget::MODE_FILTER);

$compilationContext = $targetCompiler->createCompilationContext($target);

$executor = $this->compiler->compile($rule, $targetCompiler, $compilationContext);

return $executor->filter($target, $parameters, $targetCompiler->getOperators()->getOperators(), new ExecutionContext($executionContext));

}

第一步会检查目标编译器是否支持筛选模式。

第二步创建编译上下文,这个一般统一是Context类实例public function createCompilationContext($target): Context

{

return new Context();

}

第三步,执行compiler的compile()方法public function compile(string $rule, CompilationTarget $target, Context $context): Executor

{

$context['rule_identifier'] = $this->getRuleIdentifier($target, $context, $rule);

$context['executor_classname'] = 'Executor_'.$context['rule_identifier'];

$context['executor_fqcn'] = '\RulerZ\Compiled\Executor\\Executor_'.$context['rule_identifier'];

if (!class_exists($context['executor_fqcn'], false)) {

$compiler = function () use ($rule, $target, $context) {

return $this->compileToSource($rule, $target, $context);

};

$this->evaluator->evaluate($context['rule_identifier'], $compiler);

}

return new $context['executor_fqcn']();<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值