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.

Maintainers

Package info

github.com/zxc7563598/php-simple-rule-engine

pkg:composer/hejunjie/simple-rule-engine

Transparency log

Statistics

Installs: 644

Dependents: 1

Suggesters: 0

Stars: 7

Open Issues: 0

v1.0.3 2026-07-16 06:02 UTC

This package is auto-updated.

Last update: 2026-07-16 06:05:31 UTC


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 OperatorInterface to handle specialized business needs.
  • Decoupled Rules and Data: Rule definitions are fully separated from data evaluation, supporting arrays, objects, and more.
  • Detailed Evaluation Feedback: evaluateWithDetails returns the pass/fail status of each rule, making debugging and logging straightforward.

📋 Requirements

📦 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.