geldek/math-expression

用于数学表达式的PHP解析器和评估库

dev-master 2020-08-30 12:11 UTC

This package is auto-updated.

Last update: 2024-09-29 05:55:50 UTC


README

用于数学表达式的PHP解析器和评估库。该库实现了以下功能

  • 表达式解析和评估
  • 解析十六进制、二进制和科学记数法数字
  • 变量
  • 使用匿名函数在运行时解析变量值
  • 执行自定义PHP函数
  • 扩展Expression类以执行自定义方法
  • 函数白名单

库不支持具有可变数量参数的函数。这是根据维基百科描述的Shunting-yard算法的实现。

安装

使用composer安装此包。

    composer require geldek/math-expression

用法

以下代码评估此表达式:(.1 + 2.9e3)^2 * 3 / -cos(0) + 0x1F % 0b11

    use geldek\math\Expression;
    use geldek\math\ExpressionException;
    use geldek\math\Token;

    $expression = new Expression('(.1 + 2.9e3)^2 * 3 / -cos(0) + 0x1F % 0b11');
    $tokens = $expression->parse();
    $result = $expression->calculate();
    var_dump($result);

以下代码使用变量和闭包来计算表达式计算时的变量值。

    use geldek\math\Expression;
    use geldek\math\ExpressionException;
    use geldek\math\Token;

    $expression = new Expression('var1 + var2 + z_1', [
        'var1' => 1,
        'var2' => function($name) {
             return $name == 'y' ? 2 : 3;
        }
    ]);
    $expression->setVariable('z_1', 5);
    $tokens = $expression->parse();
    $result = $expression->calculate();
    var_dump($result);

以下代码使用自定义PHP函数。

    use geldek\math\Expression;
    use geldek\math\ExpressionException;
    use geldek\math\Token;

    function mymax($a, $b) {
        return $a > $b ? $a : $b;
    }

    $expression = new Expression('mymax(2,-3)');
    $tokens = $expression->parse();
    $result = $expression->calculate();
    var_dump($result);

以下代码扩展Expression类以调用自定义方法。

    use geldek\math\Expression;
    use geldek\math\ExpressionException;
    use geldek\math\Token;

    class ExpressionEx extends Expression
    {
        public function __construct($exp, $vars = []) {
            parent::__construct($exp, $vars);
        }

        public function mymin($a, $b) {
            return $a > $b ? $b : $a;
        }
    }

    $expression = new ExpressionEx('mymin(2,-3)');
    $tokens = $expression->parse();
    $result = $expression->calculate();
    var_dump($result);

以下代码通过捕获ExpressionException来处理无效表达式。除了错误信息外,您还可以获取导致错误的标记值和位置。

    use geldek\math\Expression;
    use geldek\math\ExpressionException;
    use geldek\math\Token;

    try {
        $expression = new Expression('((1+2)+3');
        $tokens = $expression->parse();
        $result = $expression->calculate();
        var_dump($result);
    }
    catch(ExpressionException $ex) {
        $token = $ex->getToken();
        $position = $ex->getPosition();
    }

以下代码将抛出异常,因为表达式中的函数不在白名单中。

    use geldek\math\Expression;
    use geldek\math\ExpressionException;
    use geldek\math\Token;

    try {
        $expression = new Expression('cos(0)');
        $expression->setWhiteList(['sin']);
        $tokens = $expression->parse();
        $result = $expression->calculate();
        var_dump($result);
    }
    catch(ExpressionException $ex) {
        $token = $ex->getToken();
        $position = $ex->getPosition();
    }

运行测试

如果您安装了开发依赖项,可以按照以下方式运行测试

    .\vendor\bin\phpunit tests