PHP 规则引擎 HoaRuler
Hoa\Ruler 是匹配特定语法的字符串,Hoa\Ruler\Ruler 定义语言语法描述,Hoa\Ruler\Context 定义变量值,
Hoa\Ruler\Ruler::assert 执行并获得结果,结果是一个布尔值。
TP5 框架代码:
namespace app\index\controller;
use Hoa\Ruler\Context;
use Hoa\Ruler\Ruler;
class Index
{
public function index()
{
$ruler = new Ruler();
$rule = 'group in ["customer", "guest"] and points > 30';
$context = new Context();
$context['group'] = 'customer';
$context['points'] = function () {
return 42;
};
$r = $ruler->assert($rule, $context);
print_r($r);
}
}
Grammar(语法):
语法 | 说明 |
---|---|
'foo' , "foo" , 'f\'oo' |
字符串 |
true , false , null |
预先定义的常量 |
4.2 |
小数 |
42 |
整数 |
['foo', true, 4.2, 42] |
数组 |
sum(1, 2, 3) |
调用函数并给定参数 |
points |
变量 |
points['x'] |
数组指定元素 |
line.pointA |
访问对象属性 |
line.length() |
访问对象方法 |
and , or , xor , not |
逻辑运算符 |
= , != , > , < , >= , <= |
比较运算符 |
is , in |
成员操作符 |
Context(对象):
定义规则中变量的值。
1:常量、数字、字符串等标量,或数组、对象等结构化类型。
2:也可以是函数返回的值。
namespace app\index\controller;
use Hoa\Ruler\Context;
use Hoa\Ruler\Ruler;
use Hoa\Ruler\DynamicCallable;
class Index
{
public function index()
{
$context = new Context();
$i = 0;
$context['int'] = function () use (&$i) {
return ++$i;
};
var_dump(
$context['int'],
$context['int'],
$context['int'],
$i
);
$i = 0;
$context['int'] = new DynamicCallable(
function () use (&$i) {
return ++$i;
}
);
var_dump(
$context['int'],
$context['int'],
$context['int'],
$i
);
}
}
>>>
int(1) int(1) int(1) int(1) int(1) int(2) int(3) int(3)
Add functions(添加自定义方法):
样例如下:
namespace app\index\controller;
class user
{
const DISCONNECTED = 0;
const CONNECTED = 1;
protected $_status = 1;
public function getStatus()
{
return $this->_status;
}
}
namespace app\index\controller;
use Hoa\Ruler\Context;
use Hoa\Ruler\Ruler;
use Hoa\Ruler\DynamicCallable;
use Hoa\Ruler\Visitor\Asserter;
use app\index\controller\user;
class Index
{
public function index()
{
$logged = function (user $user) {
return $user::CONNECTED === $user->getStatus();
};
$ruler = new Ruler();
$rule = 'logged(user) and points > 30';
$context = new Context();
$context['user'] = new user();
$context['points'] = 42;
$asserter = new Asserter();
$asserter->setOperator('logged', $logged);
$ruler->setAsserter($asserter);
//简写:$ruler->getDefaultAsserter()->setOperator('logged', $logged);
print_r($ruler->assert($rule, $context));
}
}
>>>
1

更多精彩