Process mathematical equations in php

后端 未结 8 1910
陌清茗
陌清茗 2020-11-30 14:14

A user is allowed to enter any mathematical equation they like (with one variable):

x + 5

1 - x/2

(x/3) * (56/13)

8条回答
  •  旧巷少年郎
    2020-11-30 14:25

    My standard answer to this question whenever it crops up:

    Don't use eval (especially as you're stating that this is user input) or reinvent the wheel by writing your own formula parser.

    Take a look at the evalMath class on PHPClasses. It should do everything that you've listed here.

    EDIT

    re: Unfortunately evalMath does not handle things like (x > 5)

    change lines 177-179 to

    $ops   = array('+', '-', '*', '/', '^', '_', '>', '<', '=');
    $ops_r = array('+'=>0,'-'=>0,'*'=>0,'/'=>0,'^'=>0, '>' => 0, '<' => 0, '=' => 0); // right-associative operator?
    $ops_p = array('+'=>0,'-'=>0,'*'=>1,'/'=>1,'_'=>1,'^'=>2, '>' => 0, '<' => 0, '=' => 0); // operator precedence
    

    change line 184 to

    if (preg_match("/[^\w\s+*^\/()\.,-<>=]/", $expr, $matches)) { // make sure the characters are all good
    

    add

    case '>':
         $stack->push($op1 > $op2); break;
    case '<':
         $stack->push($op1 < $op2); break;
    case '=':
         $stack->push($op1 == $op2); break;
    

    after line 321

    and evalMath will now handle (x > 5), (x < 5) or (x = 5)

    // instantiate a new EvalMath
    $m = new EvalMath;
    $m->suppress_errors = true;
    // set the value of x
    $m->evaluate('x = 3');
    var_dump($m->evaluate('y = (x > 5)'));
    

    Further Edit

    Missed line 307 that should be modified to read:

    if (in_array($token, array('+', '-', '*', '/', '^', '>', '<', '='))) {
    

提交回复
热议问题