PHP策略模式与业务规则引擎
2026/6/2 8:40:58 网站建设 项目流程

PHP策略模式与业务规则引擎

业务规则引擎让业务逻辑可以灵活配置,不需要修改代码。PHP策略模式的扩展可以形成简单的规则引擎。今天说说PHP规则引擎的实现。

规则引擎的核心是规则的定义和执行。规则由条件(Condition)和动作(Action)组成。

```php
interface RuleCondition
{
public function evaluate(array $context): bool;
}

interface RuleAction
{
public function execute(array &$context): void;
}

class Rule
{
private string $name;
private RuleCondition $condition;
private RuleAction $action;
private int $priority;

public function __construct(string $name, RuleCondition $condition, RuleAction $action, int $priority = 0)
{
$this->name = $name;
$this->condition = $condition;
$this->action = $action;
$this->priority = $priority;
}

public function getName(): string
{
return $this->name;
}

public function getPriority(): int
{
return $this->priority;
}

public function applies(array $context): bool
{
return $this->condition->evaluate($context);
}

public function execute(array &$context): void
{
$this->action->execute($context);
}
}

// 条件实现
class GreaterThanCondition implements RuleCondition
{
public function __construct(
private string $field,
private float $value
) {}

public function evaluate(array $context): bool
{
return ($context[$this->field] ?? 0) > $this->value;
}
}

class LessThanCondition implements RuleCondition
{
public function __construct(
private string $field,
private float $value
) {}

public function evaluate(array $context): bool
{
return ($context[$this->field] ?? 0) < $this->value;
}
}

class EqualCondition implements RuleCondition
{
public function __construct(
private string $field,
private mixed $value
) {}

public function evaluate(array $context): bool
{
return ($context[$this->field] ?? null) === $this->value;
}
}

class AndCondition implements RuleCondition
{
private array $conditions;

public function __construct(RuleCondition ...$conditions)
{
$this->conditions = $conditions;
}

public function evaluate(array $context): bool
{
foreach ($this->conditions as $condition) {
if (!$condition->evaluate($context)) return false;
}
return true;
}
}

class OrCondition implements RuleCondition
{
private array $conditions;

public function __construct(RuleCondition ...$conditions)
{
$this->conditions = $conditions;
}

public function evaluate(array $context): bool
{
foreach ($this->conditions as $condition) {
if ($condition->evaluate($context)) return true;
}
return false;
}
}

class InCondition implements RuleCondition
{
public function __construct(
private string $field,
private array $values
) {}

public function evaluate(array $context): bool
{
return in_array($context[$this->field] ?? null, $this->values);
}
}

// 动作实现
class SetFieldAction implements RuleAction
{
public function __construct(
private string $field,
private mixed $value
) {}

public function execute(array &$context): void
{
$context[$this->field] = $this->value;
}
}

class ApplyDiscountAction implements RuleAction
{
public function __construct(
private float $rate,
private string $targetField = 'total'
) {}

public function execute(array &$context): void
{
$original = $context[$this->targetField] ?? 0;
$context[$this->targetField] = round($original * (1 - $this->rate), 2);
$context['discount_applied'] = $this->rate;
$context['original_total'] = $original;
}
}

class LogAction implements RuleAction
{
public function __construct(
private string $message,
private string $logFile = '/tmp/rules.log'
) {}

public function execute(array &$context): void
{
$log = sprintf(
"[%s] %s | context: %s\n",
date('Y-m-d H:i:s'),
$this->message,
json_encode($context)
);
file_put_contents($this->logFile, $log, FILE_APPEND);
}
}

class AddMessageAction implements RuleAction
{
public function __construct(
private string $message
) {}

public function execute(array &$context): void
{
$context['messages'][] = $this->message;
}
}

class RuleEngine
{
private array $rules = [];

public function addRule(Rule $rule): void
{
$this->rules[] = $rule;
}

public function addRules(array $rules): void
{
foreach ($rules as $rule) {
$this->addRule($rule);
}
}

public function execute(array &$context): array
{
$executed = [];

// 按优先级排序
usort($this->rules, fn($a, $b) => $b->getPriority() - $a->getPriority());

foreach ($this->rules as $rule) {
if ($rule->applies($context)) {
$rule->execute($context);
$executed[] = $rule->getName();
}
}

return $executed;
}
}

// 构建订单规则引擎
$engine = new RuleEngine();

$engine->addRules([
// VIP用户折扣
new Rule(
'vip_discount',
new AndCondition(
new EqualCondition('user_type', 'vip'),
new GreaterThanCondition('total', 100)
),
new ApplyDiscountAction(0.15, 'total'),
10
),

// 新用户折扣
new Rule(
'new_user_discount',
new AndCondition(
new EqualCondition('is_new_user', true),
new GreaterThanCondition('total', 50)
),
new ApplyDiscountAction(0.1, 'total'),
8
),

// 大额订单折扣
new Rule(
'bulk_discount',
new GreaterThanCondition('total', 1000),
new ApplyDiscountAction(0.05, 'total'),
5
),

// 订单满减
new Rule(
'free_shipping',
new GreaterThanCondition('total', 200),
new SetFieldAction('shipping_fee', 0),
3
),

// 节日促销
new Rule(
'holiday_promo',
new InCondition('season', ['christmas', 'new_year', 'black_friday']),
new ApplyDiscountAction(0.2, 'total'),
15
),
]);

// 执行规则
$order = [
'order_id' => 'ORD-2024-001',
'user_type' => 'vip',
'is_new_user' => false,
'total' => 1500,
'shipping_fee' => 30,
'items_count' => 10,
'season' => 'new_year',
'messages' => [],
];

$executed = $engine->execute($order);

echo "执行的规则: " . implode(', ', $executed) . "\n\n";
echo "处理结果:\n";
echo " 原始金额: {$order['original_total']}\n";
echo " 最终金额: {$order['total']}\n";
echo " 运费: {$order['shipping_fee']}\n";
echo " 折扣: " . ($order['discount_applied'] * 100) . "%\n";
echo " 消息:\n";
foreach ($order['messages'] as $msg) {
echo " - {$msg}\n";
}
?>
```

策略模式可以衍生出规则引擎,把业务规则从硬编码中解放出来。规则引擎的核心是条件评估和动作执行。设计良好的规则引擎可以让业务逻辑灵活配置,支持运营人员调整促销策略而不需要开发人员改代码。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询