美文网首页
PHP简易规则引擎

PHP简易规则引擎

作者: MrBryan | 来源:发表于2018-05-31 12:12 被阅读189次

    什么是规则引擎 能Google的就不多说了。简易概括来说,就是通过解析更易定义的规则,来执行定义的动作,包括:重新赋值,调用自定义函数。对于后端特别多逻辑的业务,规则引擎能较好地节省开发时间,降低维护成本。JAVA有很多实现,但是PHP貌似还没有实现,所以做了这个轮子。

    一、规则定义

    1.关键字 关键字非常少,只有五个:rule when then end call

    rule:定义规则名称,如 rule rulename

    when:规则的触发条件,表示其后的所有行都是条件语句,when需要单独占用一行。

    then:规则的结果语句,表示其后的所有行都将顺序执行

    call:结果语句中指定执行某函数

    end:一个规则定义的结束标记

    规则可以定义在一个文件里,一个规则文件可以定义多条规则。多个规则文件里如果有相同的规则名称,则最后一个规则会覆盖前一个规则。

    /和#用来注释

    2.语法 规则名称定义:关键字rule与规则名称以空格分隔,占用一行。

    条件语句(when后的语句):条件对象以$开头,以字母,数字或下划线组成,如 $user。语法为: $绑定变量(元素名 操作符 值[,或or]…),或者:$绑定变量操作符 值[, 或or]…。 每个条件对象都将绑定一个PHP的变量。用”:”表示多维关联数组元素,如$user:order将绑定到$user[‘order’],依次类推。()表示此数组里的多个元素,如:$user(id==100,name==Tony) ;$order(price>100)。多个条件使用“;”分隔,多个条件间的关系是与操作。如前一个示例的含义是:$user数组的成员id等于100且name等于Tony,且$order的成员price大于100,则满足条件。

    结果语句(then后的语句):结果语句可以重新对用户输入数据赋值,也可以调用用户自定义函数。重新赋值语法为:$绑定变量(成员=新值,…);如:$user:card(name=newName,id=$newid)。调用自定义函数的语法为:call(函数/方法名,参数一,参数二…),如果要调用的是自定义的某个类的方法,如以->连接类名和方法名。如call(ClassName->method, $user:card,1);如上示例,参数可以是一个新的绑定变量。当前结果语句可以引用前一个结果语句赋值的绑定变量。 结果语句赋值时支持运算符”+ - * / %” 以及字符串连接符 “.” ,字符串连接符仅支持两个变量的连接。

    代码示例:

    warehouse.drl

    //分快递
    rule AssignExpress
    when
    $address contains 北京 or $address contains 北京市;$user:card(name==zhangtao,id not memberof $userids);
    then
    $user:card(name=tony,id=new);call(TestCommand->doTest15, $user:card,1,haha);
    end

    分仓库

    rule AssignWarehouse
    when
    $user(name==zhangtao,);$order(goods_amount>100)
    then
    $order(mihome_id=120)
    end
    3.操作符

    此规则引擎支持以下操作符:

    操作符 说明 备注
    == 等于

            大于
    

    < 小于

    = 大于等于
    <= 小于等于
    != 不等于
    Memberof 属于 操作对象可以是数组,对象或字符串
    Not memberof 不属于 操作对象可以是数组,对象或字符串
    Contains 包含 操作对象可以是数组,对象或字符串
    Not contains 不包含 操作对象可以是数组,对象或字符串
    = 赋值 仅在结果语句中使用
    4.错误码定义

    $errorsCode = 【
    '41000' => 'Data's key is not exists',
    '41001' => 'Value is not an array',
    '41002' => 'Rule file format error:Rule name is not difined',
    '41003' => 'Rule name is not exists',
    '41004' => 'Value's format is wrong',
    '41005' => 'Error operator',
    '41006' => 'Operator is wrong.The right operator are:== != > < >= <= , memberof , contains , not memberof , not contains',】

    二、使用入门 首先需要引用规则引擎类,对于x5项目,如下

    x5()->import("lib/Rules.php");
    $r = new Rules();
    非x5项目,可以

    include “Rules.php”;
    $r = new Rules();
    接下来:初始化规则文件

    $r->initRulesMap("warehouse.drl");
    然后,输入要判断的数据

    $r->import($data);
    最后,调用规则

    $r->execute(‘规则名称’);

    三、实战 一个电商网站每天产生很多订单,全国有两个仓库,规则1:北京的订单需要分配到北京仓,规则2:上海的订单需要分配到上海仓。规则3:上海的订单大于100的减10块运费;北京的订单小于90元的把用户ID标记在地址前面。

    DRL文件:order.drl

    订单分配逻辑

    rule AssignOrder
    when
    $address contains 北京 or $address contains 北京市;
    then
    $user:order(mihome=北京仓)
    when
    $address contains 上海
    then
    $user:order(mihome=上海仓)
    when
    $user:order(mihome==上海仓);$user:order(price>100)
    then
    $user:order(price=$user:order:price-10)
    when
    $user:order(mihome==北京仓);$user:order(price<90)
    then
    $address=$user:order:id . $address
    end
    测试数据1:

    $data = array(
    'user' => array(
    'order' => array(
    'order_id'=>1016,
    'id' => 8888,
    'name' => 'zhangsan',
    'price' => 200,
    'mihome'=>'',
    )
    ),
    'address' => "北京市朝阳区",
    );
    执行结果前后对比1: 执行前

    Array
    (
    [user] => Array
    (
    [order] => Array
    (
    [order_id] => 1016
    [id] => 8888
    [name] => zhangsan
    [price] => 200
    [mihome] =>
    )
    )
    [address] => 北京市朝阳区
    )
    执行2

    Array
    (
    [user] => Array
    (
    [order] => Array
    (
    [order_id] => 1016
    [id] => 8888
    [name] => zhangsan
    [price] => 190
    [mihome] => 北京仓
    )
    )
    [address] => 北京市朝阳区
    )
    测试数据2:

    $data = array(
    'user' => array(
    'order' => array(
    'order_id'=>1017,
    'id' => 6666,
    'name' => 'lisi',
    'price' => 18,
    'mihome'=>'',
    )
    ),
    'address' => "上海市徐汇区",
    );
    执行结果前后对比2: 执行前

    Array
    (
    [user] => Array
    (
    [order] => Array
    (
    [order_id] => 1017
    [id] => 6666
    [name] => lisi
    [price] => 18
    [mihome] =>
    )
    )
    [address] => 上海市徐汇区
    )
    执行后

    Array
    (
    [user] => Array
    (
    [order] => Array
    (
    [order_id] => 1017
    [id] => 6666
    [name] => lisi
    [price] => 18
    [mihome] => 上海仓
    )
    )
    [address] => 6666上海市徐汇区
    )

    详情 :https://github.com/tonera/Rules

    相关文章

      网友评论

          本文标题:PHP简易规则引擎

          本文链接:https://www.haomeiwen.com/subject/illqsftx.html