hejunjie / simple-rule-engine
一个轻量、易用的 PHP 规则引擎,支持多条件组合与动态规则执行,适用于业务规则判断、数据校验等场景 | A lightweight and flexible PHP rule engine supporting complex conditions and dynamic rule execution—ideal for business logic evaluation and data validation.
Requires
- php: ^8.1
- nesbot/carbon: ^3.9
Requires (Dev)
- phpunit/phpunit: ^11.5
README
简体中文 | English
A lightweight, easy-to-use PHP rule engine supporting multi-condition combinations and dynamic rule execution — ideal for business logic evaluation and data validation.
This project has been parsed by Zread. Click to explore the project structure and code navigation.
✨ Features
- Clean API: Build and execute rules in just a few lines with
Rule+Engine, supporting AND / OR combination logic. - Rich Built-in Operators: 17 operators out of the box covering comparison, string, array, and date scenarios.
- Highly Extensible: Register custom operators by implementing the
OperatorInterfaceto handle specialized business needs. - Decoupled Rules and Data: Rule definitions are fully separated from data evaluation, supporting arrays, objects, and more.
- Detailed Evaluation Feedback:
evaluateWithDetailsreturns the pass/fail status of each rule, making debugging and logging straightforward.
📋 Requirements
- PHP >= 8.1
- nesbot/carbon ^3.9 (required by date operators)
📦 Installation
composer require hejunjie/simple-rule-engine
🚀 Quick Start
use Hejunjie\SimpleRuleEngine\Rule; use Hejunjie\SimpleRuleEngine\Engine; // 1. Define rules $rules = [ new Rule('age', '>=', 18, 'Age must be 18 or older'), new Rule('country', '==', 'SG', 'Country must be Singapore'), ]; // 2. Prepare data $data = [ 'age' => 20, 'country' => 'SG', ]; // 3. Evaluate $result = Engine::evaluate($rules, $data, 'AND'); // true
📖 Usage
Basic Evaluation
Engine::evaluate() accepts a list of rules, data, and a combination strategy, returning a boolean.
$rules = [ new Rule('score', '>=', 60, 'Score is passing'), new Rule('score', '<', 100, 'Score is not perfect'), ]; $data = ['score' => 85]; // AND: all rules must pass Engine::evaluate($rules, $data, 'AND'); // true // OR: at least one rule must pass Engine::evaluate($rules, $data, 'OR'); // true
Getting Detailed Results
Engine::evaluateWithDetails() returns the evaluation result for each rule:
$rules = [ new Rule('age', '>=', 18, 'Age must be 18 or older'), new Rule('vip', '==', true, 'Must be a VIP user'), ]; $data = ['age' => 20, 'vip' => false]; $details = Engine::evaluateWithDetails($rules, $data); // [ // ['description' => 'Age must be 18 or older', 'passed' => true], // ['description' => 'Must be a VIP user', 'passed' => false], // ]
Using RuleGroup
If you need more flexible composition (e.g., reusing the same group of rules across different scenarios), you can use RuleGroup directly:
use Hejunjie\SimpleRuleEngine\RuleGroup; $group = new RuleGroup([ new Rule('status', '==', 'active', 'Status is active'), new Rule('level', '>=', 3, 'Level is 3 or above'), ], 'AND'); $data = ['status' => 'active', 'level' => 5]; $group->evaluate($data); // true $group->evaluateWithDetails($data); // Returns detailed evaluation array
Custom Operators
Implement the OperatorInterface and register through OperatorFactory:
use Hejunjie\SimpleRuleEngine\Interface\OperatorInterface; use Hejunjie\SimpleRuleEngine\OperatorFactory; class ModOperator implements OperatorInterface { public function evaluate(mixed $fieldValue, mixed $ruleValue): bool { return $fieldValue % $ruleValue === 0; } public function name(): string { return 'mod'; } } // Register OperatorFactory::getInstance()->register(new ModOperator()); // Use $rule = new Rule('number', 'mod', 3, 'Number is divisible by 3'); $rule->evaluate(['number' => 9]); // true
🧩 Built-in Operators
Comparison Operators
| Operator | Description | Example Value |
|---|---|---|
== |
Equal to | 18 |
!= |
Not equal to | 18 |
> |
Greater than | 18 |
>= |
Greater than or equal to | 18 |
< |
Less than | 18 |
<= |
Less than or equal to | 18 |
Set Operators
| Operator | Description | Example Value |
|---|---|---|
in |
Value in array | ['SG', 'MY', 'TH'] |
not_in |
Value not in array | ['SG', 'MY', 'TH'] |
String Operators
| Operator | Description | Example Value |
|---|---|---|
contains |
Contains substring | 'admin' |
not_contains |
Does not contain substring | 'admin' |
start_swith |
Starts with | 'VIP_' |
end_swith |
Ends with | '@example.com' |
Range Operators
| Operator | Description | Example Value |
|---|---|---|
between |
Value within range | [18, 65] |
not_between |
Value outside range | [18, 65] |
Date Operators
| Operator | Description | Example Value |
|---|---|---|
before_date |
Date is before | '2025-01-01' |
after_date |
Date is after | '2025-01-01' |
date_equal |
Date is equal to | '2025-01-01' |
Date operators are powered by Carbon and support all common date formats as well as timestamps.
🎯 Use Cases
- Form Data Validation: Dynamically validate user-submitted fields against conditions.
- Business Rule Evaluation: Order status transitions, campaign eligibility, access control, and more.
- Data Filtering: Filter datasets based on predefined rules.
- Config-Driven Logic: Define rules via configuration files or databases for flexible business logic.
📁 Directory Structure
php-simple-rule-engine/
├── src/
│ ├── Engine.php # Rule engine entry point (static facade)
│ ├── Rule.php # Single rule
│ ├── RuleGroup.php # Rule group (supports AND/OR composition)
│ ├── OperatorFactory.php # Operator factory (singleton, manages registration)
│ ├── Interface/
│ │ └── OperatorInterface.php # Operator interface
│ └── Operators/ # Built-in operator implementations
│ ├── EqualOperator.php
│ ├── NotEqualOperator.php
│ ├── GreaterThanOperator.php
│ ├── GreaterThanOrEqualOperator.php
│ ├── LessThanOperator.php
│ ├── LessThanOrEqualOperator.php
│ ├── InOperator.php
│ ├── NotInOperator.php
│ ├── ContainsOperator.php
│ ├── NotContainsOperator.php
│ ├── StartsWithOperator.php
│ ├── EndsWithOperator.php
│ ├── BetweenOperator.php
│ ├── NotBetweenOperator.php
│ ├── BeforeDateOperator.php
│ ├── AfterDateOperator.php
│ └── DateEqualOperator.php
├── tests/
│ └── Operators/ # Operator unit tests
├── composer.json
├── phpunit.xml
└── README.md
🧪 Running Tests
composer install ./vendor/bin/phpunit
🙌 Contributing
If this project helps you, a Star ⭐ would be much appreciated!
For questions or suggestions, feel free to open an Issue. Let's make it better together.