- Notifications
You must be signed in to change notification settings - Fork19
PHP Rule Engine - Parses & Evaluates JavaScript-like expressions
License
nicoSWD/php-rule-parser
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
You're looking at a standalone PHP library to parse and evaluate text based rules with a Javascript-like syntax. This project was born out of the necessity to evaluate hundreds of rules that were originally written and evaluated in JavaScript, and now needed to be evaluated on the server-side, using PHP.
This library has initially been used to change and configure the behavior of certain "Workflows" (without changing actual code) in an intranet application, but it may serve a purpose elsewhere.
Via Composer
$ composer require nicoswd/php-rule-parser
This library works best with one of these bundles below, but they're not required
| Bundle | Framework | Packagist |
|---|---|---|
| nicoSWD/rule-engine-bundle | Symfony |
Test if a value is in a given array
$variables = ['coupon_code' => (string)$_POST['coupon_code'],];$rule =newRule('coupon_code in ["summer_discount", "summer21"]',$variables);var_dump($rule->isTrue());// bool(true)
Performing a regular expression
$variables = ['coupon_code' => (string)$_POST['coupon_code'],];$rule =newRule('coupon_code.test(/^summer20[0-9]{2}$/) == true',$variables);var_dump($rule->isTrue());// bool(true)
Test if a value is between a given range
$variables = ['points' =>80];$rule =newRule('points >= 50 && points <= 100',$variables);var_dump($rule->isTrue());// bool(true)
Call methods on objects from within rules
class User{publicfunctionpoints():int {return1337; }}$variables = ['user' =>newUser(),];$rule =newRule('user.points() > 300',$variables);var_dump($rule->isTrue());// bool(true)
For security reasons, PHP's magic methods like__construct and__destruct cannot becalled from within rules. However,__call will be invoked automatically if available,unless the called method is defined.
| Name | Example |
|---|---|
| charAt | "foo".charAt(2) === "o" |
| concat | "foo".concat("bar", "baz") === "foobarbaz" |
| endsWith | "foo".endsWith("oo") === true |
| startsWith | "foo".startsWith("fo") === true |
| indexOf | "foo".indexOf("oo") === 1 |
| join | ["foo", "bar"].join(",") === "foo,bar" |
| replace | "foo".replace("oo", "aa") === "faa" |
| split | "foo-bar".split("-") === ["foo", "bar"] |
| substr | "foo".substr(1) === "oo" |
| test | "foo".test(/oo$/) === true |
| toLowerCase | "FOO".toLowerCase() === "foo" |
| toUpperCase | "foo".toUpperCase() === "FOO" |
| Name | Example |
|---|---|
| parseInt | parseInt("22aa") === 22 |
| parseFloat | parseFloat("3.1") === 3.1 |
| Type | Description | Operator |
|---|---|---|
| Comparison | greater than | > |
| Comparison | greater than or equal to | >= |
| Comparison | less than | < |
| Comparison | less or equal to | <= |
| Comparison | equal to | == |
| Comparison | not equal to | != |
| Comparison | identical | === |
| Comparison | not identical | !== |
| Containment | contains | in |
| Containment | does not contain | not in |
| Logical | and | && |
| Logical | or | || |
Both,$rule->isTrue() and$rule->isFalse() will throw an exception if the syntax is invalid. These calls can either be placed inside atry /catch block, or it can be checked prior using$rule->isValid().
$ruleStr =' (2 == 2) && ( 1 < 3 && 3 == 2 ( // Missing and/or before parentheses 1 == 1 ) )';$rule =newRule($ruleStr);try {$rule->isTrue();}catch (\Exception$e) {echo$e->getMessage();}
Or alternatively:
if (!$rule->isValid()) {echo$rule->getError();}
Both will output:Unexpected token "(" at position 25 on line 3
A custom syntax highlighter is also provided.
usenicoSWD\Rule;$ruleStr =' // This is true 2 < 3 && ( // This is false foo in [4, 6, 7] || // True [1, 4, 3].join("") === "143" ) && ( // True "foo|bar|baz".split("|" /* uh oh */) === ["foo", /* what */ "bar", "baz"] && // True bar > 6 )';$highlighter =newRule\Highlighter\Highlighter(newRule\Tokenizer());// Optional custom styles$highlighter->setStyle( TokenType::VARIABLE,'color: #007694; font-weight: 900;');echo$highlighter->highlightString($ruleStr);
Outputs:
- Parentheses can be nested, and will be evaluated from right to left.
- Only value/variable comparison expressions with optional logical ANDs/ORs, are supported.
If you discover any security related issues, please emailsecurity@nic0.me instead of using the issue tracker.
$ composertestPull requests are very welcome! If they include tests, even better. This project follows PSR-2 coding standards, please make sure your pull requests do too.
- Support for object properties (foo.length)
- Support for returning actual results, other than true or false
- Support for array / string dereferencing: "foo"[1]
- Don't force boolean comparison for tokens that are already booleans.
my_func() && 2 > 1should work - Change regex and implementation for method calls. ".split(" should not be the token
- Add / implement missing methods
- Add "typeof" construct
- Do math (?)
- Allow string concatenating with "+"
- Invalid regex modifiers should not result in an unknown token
- Duplicate regex modifiers should throw an error
Add support for function callsSupport for regular expressionsFix build on PHP 7 / NightlyAllow variables in arraysVerify function and method name spelling (.tOuPpErCAse() is currently valid)- ...
About
PHP Rule Engine - Parses & Evaluates JavaScript-like expressions
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Uh oh!
There was an error while loading.Please reload this page.
Contributors4
Uh oh!
There was an error while loading.Please reload this page.

