美文网首页
规则引擎升级版(直接能跑)

规则引擎升级版(直接能跑)

作者: 嫻愔 | 来源:发表于2019-06-14 17:31 被阅读0次
    <?php
    
    class check_rule_class {
    
    }
    
    class rule{
    
        public static function check($rule, $obj) {
            $res = false;
            if (preg_match("/^\(([a-zA-Z0-9_]+)\s*(((\=|\>|\<|\>=|\<=)\s*\'?[a-zA-Z0-9\-\s\:]+\'?)|(in\s*\[(\'?[a-zA-Z0-9\-]+\'?\s*\,?\s*)+\]))\)$/", $rule, $matches)) {
                $attribute = $matches[1];
                if (strpos($rule, 'in') !== false) {
                    $rArr = explode('in', $rule);
                    $paramStr = str_replace(array('[', ']', ')', ' ', '\'', '\''), '', $rArr[1]);
                    $paramArr = explode(',',$paramStr);
                    $res = in_array($obj->$attribute, $paramArr);
                } else {
                    $r = $rule;
                    if (preg_match('/[a-zA-Z0-9_]+\s*=/', $rule, $params)) $r = str_replace('=', '==', $rule);
                    $atibute = $obj->$attribute;
                    $res = eval('return ($atibute'.str_replace($attribute, '', substr($r, 1)).";");
                }
            }
            return $res;
        }
    
        public static function check_rule($ruleStr, $ruleClass) {
            $GLOBALS['log']->fatal('start-check-rule-------'.$ruleStr);
            if (preg_match_all("/\([a-zA-Z0-9_]+\s*(((=|\>|\<|\>=|\<=)\s*\'?[a-zA-Z0-9\-\s\:]+\'?)|(in\s*\[(\'?[a-zA-Z0-9\-]+\'?\s*\,?\s*)+\]))\)/", $ruleStr, $rules)) {
                foreach ($rules[0] as $rule) {
                    $ruleRes = self::check($rule, $ruleClass);
                    $ruleStr = str_replace($rule, (int)$ruleRes, $ruleStr);
                }
                $GLOBALS['log']->fatal('the-end-rule-----'.$ruleStr);
                if (!preg_match('/[^(0|1|and|or|!|\(|\)|\s)]/', $ruleStr)) {
                    return eval('return '.str_replace(array('and', 'or'), array(' and ', ' or '), $ruleStr).";");
                }
            }
            return false;
        }
    }
    
    /**
     * 调用示例
     $class = new check_rule_class();
    $class->a = '2';
    $class->b = 5;
    $res = rule::check_rule("!(a=2) or (b in [2, '5'])", $class);
    var_dump($res); */
    

    利用了php的魔术方法

    相关文章

      网友评论

          本文标题:规则引擎升级版(直接能跑)

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