不知道你有沒有這種感覺:一個業務功能看起來很簡單,但判斷條件卻一大堆。
什麼用户狀態、配置項、商品屬性、會員等級……
一大堆 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,一起完善它 🙌
如果你覺得有幫助,點個讚我會更有動力更新下去~