Skip to content

jamoli/php-rule-parser

 
 

Repository files navigation

Rules Parser and Evaluator for PHP 5.4+

Build Status Code Quality Coverage HHVM
v0.3 Build status Code Quality Coverage Status HHVM Tested
Master Build status Code Quality Build status HHVM Tested
Develop Build Status Code Quality Coverage Status HHVM Tested

Latest Stable Version

You're looking at a 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.

Find me on Twitter: @nicoSWD

SensioLabsInsight

Install

Via Composer

$ composer require "nicoswd/php-rule-parser": "0.3.*"

Via git

$ git clone git@github.com:nicoSWD/php-rule-parser.git

Usage

use nicoSWD\Rules\Rule;

// Composer install
require '/path/to/vendor/autoload.php';
// Non-Composer install
require '/path/to/src/nicoSWD/Rules/Autoloader.php';

$ruleStr = '
    2 < 3 && (
        // False
        foo in [4, 6, 7] ||
        // True
        [1, 4, 3].join("") === "143" &&
        // True
        "bar" in "foo bar".split(" ") &&
        // True
        "foo bar".substr(4) === "bar"
    ) && (
        // True
        "foo|bar|baz".split("|") === ["foo", /* what */ "bar", "baz"] &&
        // True
        bar > 6
    )';

$variables = [
    'foo' => 'abc',
    'bar' => 321,
    'baz' => 123
];

$rule = new Rule($ruleStr, $variables);

var_dump($rule->isTrue()); // bool(true)

Error Handling

Both, $rule->isTrue() and $rule->isFalse() will throw an exception if the syntax is invalid. These calls can either be placed inside a try / 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 = new Rule($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

Syntax Highlighting

A custom syntax highlighter is also provided.

use nicoSWD\Rules;

$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 = new Rules\Highlighter(new Rules\Tokenizer());

// Optional custom styles
$highlighter->setStyle(
   Rules\Constants::GROUP_VARIABLE,
   'color: #007694; font-weight: 900;'
);

echo $highlighter->highlightString($ruleStr);

Outputs:

Syntax preview

Supported Operators

  • Equal: ==, === (strict)
  • Not equal: !=, !== (strict)
  • Greater than: >
  • Less than: <
  • Greater than/equal: >=
  • Less than/equal: <=
  • In: in

Notes

  • Parentheses can be nested, and will be evaluated from right to left.
  • Only value/variable comparison expressions with optional logical ANDs/ORs, are supported. This is not a full JavaScript emulator.

Security

If you discover any security related issues, please email security@nic0.me instead of using the issue tracker.

Testing

$ phpunit

Contributing

Pull 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.

To Do

  • Support for object properties (foo.length)
  • Support for returning actual results, other than true or false
  • Support for array / string dereferencing: "foo"[1]
  • 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 "+"
  • Support for objects {} (?)
  • Invalid regex modifiers should not result in an unknown token
  • Duplicate regex modifiers should throw an error
  • Add support for function calls
  • Support for regular expressions
  • Fix build on PHP 7 / Nightly
  • Allow variables in arrays
  • Verify function and method name spelling (.tOuPpErCAse() is currently valid)
  • ...

License

License

About

PHP Rule Parser and Evaluator - Parses JavaScript-like expressions

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • PHP 100.0%