
本文介绍一种通用、高效的递归 php 函数,用于解析任意深度嵌套的 `and`/`or` 逻辑节点数组,准确计算其布尔结果,适用于 laravel 等 php 应用中的动态规则引擎或条件求值场景。
在构建动态权限控制、业务规则引擎或条件过滤器(如高级搜索、风控策略)时,常需将逻辑结构以 JSON 形式存储并运行时求值。上述数据结构本质上是一棵多叉逻辑表达式树:每个节点含 "nodeType" 字段("and" 或 "or"),其余键(如 "0", "1", "3" 等)为子表达式——这些键名无语义,仅作索引,真正重要的是其值(布尔字面量或子节点对象)。
由于树的深度与分支数完全动态,迭代遍历极易出错且难以维护,递归是自然且最优的选择。核心思路是:
- ✅ 基础情况(Base Case):若当前值为 true 或 false,直接返回;
- ✅ 递归情况(Recursive Case):根据 nodeType 决定短路策略:
- "or" 节点:只要任一子节点返回 true,立即返回 true(OR 短路);
- "and" 节点:只要任一子节点返回 false,立即返回 false(AND 短路);
- ✅ 收尾逻辑:若遍历完所有子节点均未触发短路,则 "or" 返回 false,"and" 返回 true(即默认值取逻辑恒等元)。
以下是经过验证、鲁棒性强的实现:
function evaluateBooleanExpression($expr): bool
{
// 基础情况:已是布尔值,直接返回
if (is_bool($expr)) {
return $expr;
}
// 非数组或缺少 nodeType,视为无效节点(可按需抛异常)
if (!is_array($expr) || !isset($expr['nodeType'])) {
throw new InvalidArgumentException('Invalid expression: missing "nodeType" or not an array');
}
$isOrNode = $expr['nodeType'] === 'or';
$shortCircuitValue = $isOrNode; // OR 短路于 true;AND 短路于 false
// 遍历所有非 "nodeType" 的子项
foreach ($expr as $key => $value) {
if ($key === 'nodeType') {
continue;
}
$childResult = evaluateBooleanExpression($value);
if ($childResult === $shortCircuitValue) {
return $shortCircuitValue; // 触发短路
}
}
// 未短路:OR 全为 false → 返回 false;AND 全为 true → 返回 true
return !$shortCircuitValue;
}使用示例与验证
假设你从数据库或 API 获取如下 JSON 字符串(注意外层为单元素数组):
$json = '[
{
"nodeType": "and",
"0": {
"nodeType": "and",
"0": {
"nodeType": "and",
"1": true,
"2": false
},
"3": true
},
"2": {
"nodeType": "or",
"4": false,
"5": true
}
}
]';
$data = json_decode($json, true);
$result = evaluateBooleanExpression($data[0]); // 取首个元素
var_dump($result); // 输出: bool(false) ✅ 符合预期(最内层 and(1:true, 2:false) = false,导致顶层 and 整体为 false)关键注意事项
- ? 键名无关性:函数自动跳过 "nodeType" 键,其余所有键均视为子表达式入口,完全兼容 "0", "1", "3", "4" 等任意数字或字符串键;
- ? 严格类型安全:使用 is_bool() 判定基础值,避免 0/1、"true"/"false" 等松散类型干扰;
- ? 短路优化:无需遍历整棵树,在满足逻辑条件时立即终止,性能随表达式复杂度提升而显著受益;
- ? 错误防护:对缺失 nodeType 或非数组输入主动抛异常,便于调试与集成测试;
- ? Laravel 集成建议:可封装为 app/Helpers/LogicEvaluator.php 辅助函数,或定义为 LogicExpression 服务类,配合依赖注入使用。
该方案已通过多层嵌套(含 and→or→and→... 混合)、边界 case(纯叶子节点、空子节点等)充分验证,是生产环境中处理动态布尔逻辑表达式的可靠实践。










