動態

詳情 返回 返回

判斷邏輯越寫越亂,我乾脆做了個自己的規則引擎 - 動態 詳情

不知道你有沒有這種感覺:一個業務功能看起來很簡單,但判斷條件卻一大堆。
什麼用户狀態、配置項、商品屬性、會員等級……
一大堆 if​ / else​ 交織在一起,越寫越亂,稍微改一個邏輯就要擔心影響其他地方。

我之前就遇到這樣的情況,一開始還能忍,後來乾脆決定:不如自己寫一個簡單的規則引擎,專門用來處理這些組合判斷。

於是就有了這個項目:hejunjie/simple-rule-engine


🚀 這個規則引擎能幹嘛?

一句話總結:
這是一個輕量、易用的 PHP 規則引擎,支持多條件組合、動態規則執行,適合業務規則判斷、數據校驗等場景。

適合用在你項目中的這些地方:

  • 複雜業務的多條件判斷(比如用户是否滿足某個活動要求)
  • 數據入庫前的規則校驗
  • 自定義邏輯的配置化、結構化處理
  • 寫得一手 if 地獄,想抽出來整整齊齊 😅

🌟 為什麼要做它?

在實際業務中,很多業務判斷邏輯其實都可以歸納為:“一堆字段 + 一些規則 + 多個條件組合”。

原本我們可能是這麼寫的:

if (
    $user['status'] === 'active' &&
    $user['age'] >= 18 &&
    in_array($user['role'], ['admin', 'editor'])
) {
    // ...
}

現在可以這樣:

// 定義規則
$rules = [
    new Rule('age', '>=', 18, '年齡必須大於等於18歲'),
    new Rule('status', '==', 'active', '狀態必須為active'),
    new Rule('role', 'in', ['admin', 'editor'], '角色需擁有權限'),
];
// 評估結果
$result = Engine::evaluate($rules, $user, 'AND'); // 返回 true 或 false

// 獲取詳細評估信息(用於獲取每條規則的執行情況)
$details = Engine::evaluateWithDetails($rules, $user);
/*
返回示例:
[
    ['description' => '年齡必須大於等於18歲', 'passed' => true],
    ['description' => '狀態必須為active', 'passed' => true],
    ['description' => '角色需擁有權限', 'passed' => true]
]
*/

是不是整潔多了?而且如果你把規則放數據庫,就能實現“業務判斷配置化”了。


🧩 項目特點

  • 輕量易用:無依賴,無框架限制,簡單幾行就能用
  • 🔌 工廠註冊機制:你可以自己寫新的操作符(Operator)註冊進來
  • 📦 內置常用操作符:多數常用操作符都支持(可見文章末尾操作符支持列表)
  • 🧠 可組合、多條件支持:支持 AND / OR 關係組合,擴展多套規則邏輯很方便

📦 安裝方法

composer require hejunjie/simple-rule-engine

🛠️ 示例代碼

use Hejunjie\SimpleRuleEngine\Rule;
use Hejunjie\SimpleRuleEngine\Engine;

// 定義規則
$rules = [
    new Rule('age', '>=', 18, '年齡必須大於等於18歲'),
    new Rule('status', '==', 'active', '狀態必須為active'),
    new Rule('role', 'in', ['admin', 'editor'], '角色需擁有權限'),
];

$data = ['age' => 20, 'country' => 'China'];

// 簡單判斷是否通過全部規則
if (Engine::evaluate($rules, $data, 'AND')) {
    echo '符合規則';
}

// 獲取每一條規則是否通過的詳情
foreach (Engine::evaluateWithDetails($rules, $data) as $detail) {
    echo $detail['description'] . ':' . ($detail['passed'] ? '✅ 通過' : '❌ 未通過') . PHP_EOL;
}

🔌 自定義操作符

你可以自由的去實現自己的判斷邏輯,指定一個操作符,並自由的插入到你的規則中

僅需要實現 OperatorInterface​ 接口,並通過 OperatorFactory​ 註冊即可:

use Hejunjie\SimpleRuleEngine\Interface\OperatorInterface;
use Hejunjie\SimpleRuleEngine\OperatorFactory;

class CustomizeOperator implements OperatorInterface
{
    /**
     * 評估方法
     *
     * @param mixed $fieldValue 用户輸入數據
     * @param mixed $ruleValue 對比數據
     *
     * @return bool
     */
    public function evaluate(mixed $fieldValue, mixed $ruleValue): bool
    {
        // TODO: 實現判斷邏輯
    }

    /**
     * 操作符名稱
     *
     * @return string
     */
    public function name(): string
    {
        return 'customize';
    }
}

// 註冊自定義操作符 customize
$factory = OperatorFactory::getInstance();
$factory->register(new CustomizeOperator());

// 可以在定義規則時使用 customize
$rules = [
    new Rule('field', 'customize', 'value', '自定義規則描述'),
    ...
    ...
];

// Engine::evaluate($rules, $data, 'AND')
// Engine::evaluateWithDetails($rules, $data)

🧩 內置操作符列表

操作符 描述 額外説明
== 等於
!= 不等於
> 大於
>= 大於等於
< 小於
<= 小於等於
in 包含於集合中 數組:[內容 1,內容 2,...]
not_in 不包含於集合中 數組:[內容 1,內容 2,...]
contains 包含字符串
not_contains 不包含字符串
start_swith 以指定字符串開頭
end_swith 以指定字符串結尾
between 在指定範圍內 數組:[最大值,最小值]
not_between 不在指定範圍內 數組:[最大值,最小值]
before_date 日期早於 任意常規日期格式,包括時間戳均可
after_date 日期晚於 任意常規日期格式,包括時間戳均可
date_equal 日期相等 任意常規日期格式,包括時間戳均可

🤔 總結一下

這個規則引擎不是為了解決多麼高級的技術難題,它只是一個更優雅的解決方式
如果你也遇到過類似的 if/else 困擾,希望這個小工具能幫上你一點忙。


歡迎 Star、Issue、PR,一起完善它 🙌
如果你覺得有幫助,點個讚我會更有動力更新下去~

user avatar shuyixiaobututou 頭像
點贊 1 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.