PHP前端到PHP规则引擎

时间:2013-10-28 19:38:25

标签: javascript php design-patterns rule-engine rule

我要做的是创建一个基于Web的规则引擎,用户可以在其中创建条件语句,将它们存储在数据库中,然后在数据集上执行它们。 (例如,如果颜色等于绿色,则在描述中添加一些内容)

所以我正在考虑使用JavaScript前端规则构建器(https://github.com/joshuamcginnis/rules-builder)在JSON中构建表达式,并将该命令表达式存储在MongoDB中。

现在当这些规则需要执行时,它们会从数据库中提取出来,并通过统治者构建和执行 - 无状态PHP规则引擎(https://github.com/bobthecow/Ruler

对我来说,缺少的部分是如何将JSON命令转换为Ruler理解的链式PHP命令?是否有一种设计模式可以解决这样的问题?

4 个答案:

答案 0 :(得分:1)

所以这听起来像你将要编写一个解析器(或解释器),一个可以评估equalequalOrGreaterThan或短synax =和{{}}等命令的解析器。来自JSON文件的{1}}并根据这些命令构建表达式。

看一下这个链接http://www.slideshare.net/relaxnow/lets-build-a-parser,它会让你深入了解我的意思。我希望我可以引用它,但它是幻灯片。

答案 1 :(得分:0)

我认为击球手方法是使用服务规则引擎并将其作为服务公开。然后你的javascript应用程序可以简单地与服务进行通信,执行和操作规则。

这种方法的好处是你的规则执行不会发生在客户端上,你可以做有趣的事情,比如连接数据库后端而不会损害任何东西,并将任务作为你的规则行为来运行。值得一提的是,并非所有规则都能够在客户端执行,因为不同类型的依赖关系:数据,服务,资源......因此,最好在服务器端(在大多数情况下)运行它们。最重要的是,当在服务器上运行时,这些规则可以在多个客户端之间共享。

作为示例,您可以检查decision as a service sample并查看通用JavaScript如何与服务器通信以便执行。

答案 2 :(得分:0)

我们刚刚发布并积极支持名为Gandalf的项目,您可以在此处找到它:http://gandalf.nebo15.com。 Gandalf由两个独立的项目组成:决策引擎后端和前端。

我看起来如果符合您的需求,除了它构建在不同的库上。

您的利弊:

  • 您不需要重新发明GUI,或担心后端支持。
  • 但您需要删除当前解决方案并通过API使用新解决方案。

答案 3 :(得分:0)

这是一个古老的问题,但是今天(2020年2月)有一个很好的程序包可以准确地解决您的问题。 签出:https://github.com/nicoSWD/php-rule-parser

您可以存储纯文本规则,然后使用此程序包对其进行解析并执行。 它确实很酷,例如以下简单语句:

       $(function() {
          $('#sortable').sortable({
            start: function(event, ui) {
              var start_pos = ui.item.index();
              ui.item.data('start_pos', start_pos);
            },
            change: function(event, ui) {
              var start_pos = ui.item.data('start_pos');
              var index = ui.placeholder.index();


              cIndex = (start_pos < index) ? index - 2 : index - 1;
              ui.placeholder.prevAll('div').each(function() {
                $this = $(this);
                if ($this.is(ui.item)) {
                  return;
                }
                $this.html(cIndex);
                cIndex--;
              });

              cIndex = (start_pos < index) ? index : index + 1;
              ui.placeholder.nextAll('div').each(function() {
                $this = $(this);
                if ($this.is(ui.item)) return;
                $this.html(cIndex)
                cIndex++;
              });

              ui.item.html((start_pos < index) ? index - 1 : index);
            },
            axis: 'y'
          });
        });

或更复杂的东西:

$variables = ['foo' => 6];
$rule = new Rule('foo in [4, 6, 7]', $variables);
var_dump($rule->isTrue()); // bool(true)

我希望它能满足您的需求。