PHP code example of rogervila / php-simple-rules-engine

1. Go to this page and download the library: Download rogervila/php-simple-rules-engine library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

rogervila / php-simple-rules-engine example snippets


use SimpleRulesEngine\Rule;
use SimpleRulesEngine\Evaluation;
use SimpleRulesEngine\RulesEngine;

class FooRule extends Rule {
    public function evaluate(mixed $subject, ?Evaluation $previousEvaluation = null): Evaluation
    {
        return new Evaluation(
            result: $subject === 'foo', // mixed. It should contain the evaluation result defined by the user.
            stop: false, // false by default. When set to true, the evaluation process is stopped.
        );
    }
}

$evaluation = RulesEngine::run(
    subject: 'foo',
    rules: [new FooRule()]
);

var_dump($evaluation->getResult()); // bool(true)
var_dump($evaluation->getRule()::class); // string(7) "FooRule"

use SimpleRulesEngine\Rule;
use SimpleRulesEngine\Evaluation;
use SimpleRulesEngine\RulesEngine;

class RuleA extends Rule {
    // ...
}

class RuleB extends Rule {
    // ...
}

class RuleC extends Rule {
    // ...
}

$rules = [new RuleA(), new RuleB(), new RuleC()];

// Let's pretend that the final evaluation comes from RuleC()
$evaluation = RulesEngine::run(
    subject: 'C',
    rules: $rules,
    withHistory: true
);

var_dump(count($evaluation->getHistory())); // int(2)
var_dump($evaluation->getHistory()[0]->getRule()::class); // string(5) "RuleA"
var_dump($evaluation->getHistory()[1]->getRule()::class); // string(5) "RuleB"

use SimpleRulesEngine\Evaluation;
use SimpleRulesEngine\RulesEngine;


$rules = [
    new ARule(), // 0
    new BRule(), // 1
    [
        new AARule(), // 2
        [
            new AAARule(), // 3
            new AABRule(), // 4
            new AACRule(), // 5
        ]
    ],
    new CRule() // 6
];

$evaluation = RulesEngine::run(
    subject: '...',
    rules: $rules
);

use SimpleRulesEngine\Rule;
use SimpleRulesEngine\Evaluation;
use SimpleRulesEngine\RulesEngine;

$amex = '375678956789765';
$visa = '4345634566789888';
$mastercard = '2228345634567898';
$invalid = uniqid('invalid card ');

class AmexRule extends Rule {
    public function evaluate(mixed $subject, ?Evaluation $previousEvaluation = null): Evaluation
    {
        return new Evaluation(
            result: $result = preg_match('/^3[47][0-9]{13}$/', strval($subject)) === 1 ? 'amex' : null,
            stop: $result !== null,
        );
    }
};

class VisaRule extends Rule {
    public function evaluate(mixed $subject, ?Evaluation $previousEvaluation = null): Evaluation
    {
        return new Evaluation(
            result: $result = preg_match('/^4[0-9]{12}(?:[0-9]{3})?$/', strval($subject)) === 1 ? 'visa' : null,
            stop: $result !== null,
        );
    }
};

class MastercardRule extends Rule {
    public function evaluate(mixed $subject, ?Evaluation $previousEvaluation = null): Evaluation
    {
        return new Evaluation(
            result: $result = preg_match('/(5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|2720)[0-9]{12}/', strval($subject)) === 1 ? 'mastercard' : null,
            stop: $result !== null,
        );
    }
};


$rules = [new VisaRule(), new AmexRule(), new MastercardRule()];

shuffle($rules); // Rules should apply always, the order does not matter

$evaluation = RulesEngine::run($amex, $rules);
var_dump($evaluation->getResult()); // string(4) "amex"
var_dump($evaluation->getRule()::class); // string(8) "AmexRule"

$evaluation = RulesEngine::run($visa, $rules);
var_dump($evaluation->getResult()); // string(4) "visa"
var_dump($evaluation->getRule()::class); // string(8) "VisaRule"

$evaluation = RulesEngine::run($mastercard, $rules);
var_dump($evaluation->getResult()); // string(10) "mastercard"
var_dump($evaluation->getRule()::class); // string(14) "MastercardRule"

$evaluation = RulesEngine::run($invalid, $rules);
var_dump($evaluation->getResult()); // NULL
var_dump($evaluation->getRule()::class); // Since we are using shuffle here, the rule applied can be any of the rules previously passed

use SimpleRulesEngine\Rule;
use SimpleRulesEngine\Evaluation;
use SimpleRulesEngine\RulesEngine;

class Animal {
    public string $eats = '';
    public string $lives = '';
    public string $color = '';
};

$frog = new Animal();
$frog->eats = 'flies';
$frog->lives = 'water';
$frog->color = 'green';

$bird = new Animal();
$bird->eats = 'worms';
$bird->lives = 'nest';
$bird->color = 'black';

class EatsRule extends Rule {
    public const FACTS = ['flies' => 'frog', 'worms' => 'bird'];

    public function evaluate(mixed $subject, ?Evaluation $previousEvaluation = null): Evaluation
    {
        $previousResult = $previousEvaluation?->getResult();
        $currentResult = self::FACTS[$subject?->eats];

        return new Evaluation(
            result: $currentResult,
            stop: $previousResult === $currentResult,
        );
    }
};

class LivesRule extends Rule {
    public const FACTS = ['water' => 'frog', 'nest' => 'bird'];

    public function evaluate(mixed $subject, ?Evaluation $previousEvaluation = null): Evaluation
    {
        $previousResult = $previousEvaluation?->getResult();
        $currentResult = self::FACTS[$subject?->lives];

        return new Evaluation(
            result: $currentResult,
            stop: $previousResult === $currentResult,
        );
    }
};

class ColorRule extends Rule {
    public const FACTS = ['green' => 'frog', 'black' => 'bird'];

    public function evaluate(mixed $subject, ?Evaluation $previousEvaluation = null): Evaluation
    {
        $previousResult = $previousEvaluation?->getResult();
        $currentResult = self::FACTS[$subject?->color];

        return new Evaluation(
            result: $currentResult,
            stop: $previousResult === $currentResult,
        );
    }
};

$rules = [new EatsRule(), new LivesRule(), new ColorRule()];

shuffle($rules); // Rules should apply always, the order does not matter

$evaluation = RulesEngine::run($frog, $rules);
var_dump($evaluation->getResult()); // string(4) "frog"

$evaluation = RulesEngine::run($bird, $rules);
var_dump($evaluation->getResult()); // string(4) "bird"