本文目录导读:

在 PHP 中,“规则流”通常指根据规则(条件)控制程序执行流程,这里为你梳理几种常见的“规则流”实现方式,从基础到高级:
基础条件流(if/else)
最直接的规则判断。
<?php
$age = 25;
$isMember = true;
// 规则:会员且年龄≥18,享受折扣
if ($isMember && $age >= 18) {
echo "享受会员折扣";
} elseif ($age >= 18) {
echo "普通用户";
} else {
echo "未成年人";
}
?>
匹配流(match表达式 - PHP 8+)
适合一对一精确匹配,比 switch 更简洁。
<?php
$status = 200;
$message = match ($status) {
200, 201 => "成功",
404 => "未找到",
500 => "服务器错误",
default => "未知状态"
};
echo $message; // 输出:成功
?>
规则引擎(重点)
当规则复杂到无法用 if/else 维护时,需要规则引擎。
1 数组配置 + 循环(最简单)
<?php
// 规则表(可存数据库或配置文件)
$rules = [
['score' => 90, 'grade' => 'A', 'color' => 'green'],
['score' => 80, 'grade' => 'B', 'color' => 'blue'],
['score' => 60, 'grade' => 'C', 'color' => 'yellow'],
['score' => 0, 'grade' => 'D', 'color' => 'red'],
];
$score = 85;
foreach ($rules as $rule) {
if ($score >= $rule['score']) {
echo "等级: {$rule['grade']}, 颜色: {$rule['color']}";
break;
}
}
// 输出:等级: B, 颜色: blue
?>
2 策略模式(面向对象)
适合每种规则有不同复杂逻辑的场景。
<?php
interface DiscountRule {
public function calculate(float $price): float;
}
// 规则1:满100减20
class FullReductionRule implements DiscountRule {
public function calculate(float $price): float {
return $price >= 100 ? $price - 20 : $price;
}
}
// 规则2:会员8折
class MemberDiscountRule implements DiscountRule {
public function calculate(float $price): float {
return $price * 0.8;
}
}
// 规则流控制器
class RuleEngine {
private array $rules = [];
public function addRule(DiscountRule $rule): void {
$this->rules[] = $rule;
}
public function apply(float $price): float {
foreach ($this->rules as $rule) {
$price = $rule->calculate($price);
}
return $price;
}
}
// 使用
$engine = new RuleEngine();
$engine->addRule(new FullReductionRule());
$engine->addRule(new MemberDiscountRule());
echo $engine->apply(150); // 150-20=130, 130*0.8=104
?>
3 开源规则引擎
-
RulerZ:使用 DSL(领域特定语言)描述规则
$rule = 'price >= 100 and status = "active"'; $isValid = $rulerz->satisfies($order, $rule);
-
PHP Rules Engine:可定义复杂逻辑树
工作流流程(Workflow)
如果规则流涉及多个步骤、状态转换,推荐 Symfony Workflow:
// 定义状态机
$workflow = new Workflow(
'blog_publishing',
[
new Definition(['draft', 'review', 'published'], [
new Transition('to_review', 'draft', 'review'),
new Transition('publish', 'review', 'published'),
])
]
);
规则优先级与短路
<?php
$rules = [
['condition' => fn($v) => $v > 100, 'action' => 'high'],
['condition' => fn($v) => $v > 50, 'action' => 'medium'],
['condition' => fn($v) => $v > 0, 'action' => 'low'],
];
function fire($value, array $rules) {
foreach ($rules as $rule) {
if ($rule['condition']($value)) {
return $rule['action']; // 短路返回
}
}
return 'default';
}
echo fire(80, $rules); // medium
?>
数据库驱动的规则流(产品级)
// rules 表
// id | name | priority | condition_json | action_json
$rules = DB::table('rules')
->orderBy('priority', 'desc')
->get();
foreach ($rules as $rule) {
$condition = json_decode($rule->condition_json, true);
// 解析条件并执行...
}
选择哪种方式?
| 场景 | 推荐方法 |
|---|---|
| 简单 if/else | 直接用条件判断 |
| 多个精确匹配 | match 表达式 |
| 规则可配置、需频繁修改 | 数组/DB 驱动 + 循环 |
| 每种规则逻辑复杂 | 策略模式 + 规则引擎 |
| 系统级工作流(状态转换) | Symfony Workflow |
最佳实践:
- 规则尽量数据化(存 DB/JSON),而不是硬编码
- 使用优先级控制规则顺序
- 注意短路与互斥规则处理
如果你有具体的业务场景(比如电商促销、审批流),可以说更详细些,我可以给出更定制化的方案!