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