承接 kevintherm/exprc 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

kevintherm/exprc

Composer 安装命令:

composer require kevintherm/exprc

包简介

Convert expression string to in-memory evaluation, SQL syntax, or something else.

README 文档

README

Exprc is a tiny, decoupled rule engine for PHP

It parses rule strings into an AST once, then lets you evaluate that AST with different backends:

  • in-memory records
  • Laravel query builders
  • custom callback handlers

Prerequisites

  • PHP 8.2+

Install

composer require kevintherm/exprc

For Laravel QueryBuilder support:

composer require illuminate/database

Architecture

Rule string -> Lexer -> Parser -> AST -> Evaluator

Core parser and AST are framework-agnostic. Evaluators are swappable adapters.

Supported Operators

  • = / !=
  • > / >= / < / <=
  • LIKE / NOT LIKE
  • IN / NOT IN
  • CONTAINS / NOT CONTAINS
  • IS NULL / IS NOT NULL

Logical Operators & Precedence

Exprc uses SQL-style keywords for logical operations. Symbols like && or || are not supported.

  • NOT: Inverts the following expression (Highest precedence)
  • AND: Matches only if both sides are true
  • OR: Matches if either side is true (Lowest precedence)

Use parentheses ( ) to group expressions and override default precedence: status = 'active' AND (priority = 'high' OR is_urgent = true)

Comparison Values

  • Literals: 'strings', "strings", 42, 10.5, true, false, null
  • Identifiers: Unquoted words on the right side are treated as field paths (e.g., verified = original_verified)
  • Arrays: ['a', 'b'] or (1, 2, 3)
<?php

use Kevintherm\Exprc\Exprc;

$exprc = new Exprc();

$rule = "user.status = 'active' AND score >= 42";
$record = [
    'user' => ['status' => 'active'],
    'score' => 100,
];

$matches = $exprc->matches($rule, $record);
// true

Parse Once, Evaluate Many

<?php

use Kevintherm\Exprc\Exprc;
use Kevintherm\Exprc\Evaluators\InMemoryEpvaluator;
use Kevintherm\Exprc\Evaluators\CallbackEvaluator;

$exprc = new Exprc();
$ast = $exprc->parse("status IN ['active','pending'] AND tags CONTAINS 'beta'");

$inMemory = InMemoryEvaluator::for([
    'status' => 'active',
    'tags' => ['beta', 'pro'],
])->evaluate($ast);

$callback = CallbackEvaluator::for(function ($comparison): bool {
    return $comparison->field === 'status' && $comparison->value === 'active';
})->evaluate($ast);

Query Builder Usage (Laravel)

Exprc uses Laravel query methods for JSON paths and containment. No raw SQL is generated.

<?php

use Kevintherm\Exprc\Exprc;
use Kevintherm\Exprc\Resolvers\CollectionFieldResolver;

$exprc = new Exprc();
$ast = $exprc->parse("metadata['version'] = 'v2' AND tags CONTAINS 'beta'");

$resolver = new CollectionFieldResolver(
    tableAlias: 'r',
    fieldMap: [
        'status' => 'state',
    ],
);

$query = DB::table('rules as r');
QueryBuilderEvaluator::for($query, $resolver)->evaluate($ast);

$results = $query->get();

Field Access

Supported syntax for parser and in-memory backend:

  • dot notation: user.profile.name
  • bracket notation: tags[0], metadata['key']
  • wildcard notation: items[*]

Array Literals

Use either brackets or parentheses:

  • ['active', 'pending']
  • ('active', 'pending')
  • [1, 'two', true, null]
  • [] or ()

Extension & Customization

Exprc is designed to be highly extensible via composition and visitors.

AST Node Visitors

You can traverse the AST before evaluation for static analysis or transformation using the VisitorInterface.

use Kevintherm\Exprc\Ast\VisitorInterface;
use Kevintherm\Exprc\Ast\ComparisonNode;

class RelationshipFinder implements VisitorInterface {
    public array $relationships = [];
    
    public function visitComparisonNode(ComparisonNode $node): mixed {
        if (str_contains($node->field, '.')) {
            $this->relationships[] = explode('.', $node->field)[0];
        }
        return null;
    }
    // ... implement other methods
}

$finder = new RelationshipFinder();
$ast->accept($finder);
// $finder->relationships now contains all base relations found in the rule

Custom AST Nodes & Evaluator Hooks

All core classes are non-final. You can extend ComparisonNode to create specialized nodes (like VeloquentComparisonNode) or use evaluator hooks:

class MyEvaluator extends InMemoryEvaluator {
    public function beforeProcessNode(Node $node): void {
        // Intercept node before evaluation
    }

    public function afterProcessNode(Node $node, mixed $result): void {
        // Log or transform result
    }
}

Extensible Parsing

The Lexer and Parser classes can be extended. Use the TokenRegistry to prepare for custom symbols (like @ for system variables or -> for JSON paths).

Notes

  • AST nodes are readonly value objects (PHP 8.2+).
  • Metadata-aware nodes can be created by extending base node classes.
  • Evaluators support standard hooks for plugin-like behavior.
  • IS NULL and IS NOT NULL are treated as first-class NullComparisonNode objects.

统计信息

  • 总下载量: 225
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 0
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-04-03

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固