每当这个问题出现时,我的标准答案是:
不要使用 eval (特别是当您声明这是用户输入时)或通过编写自己的公式解析器重新发明轮子。
看看evalMath http://www.phpclasses.org/package/2695-PHP-Safely-evaluate-mathematical-expressions.htmlPHPClasses 上的类。它应该可以完成您在此处列出的所有操作。
EDIT
回复:不幸的是 evalMath 不能处理 (x > 5) 之类的事情
将第 177-179 行更改为
$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
将第 184 行更改为
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;
第321行之后
evalMath 现在将处理 (x > 5)、(x
// 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)'));
进一步编辑
缺少第 307 行,应修改为:
if (in_array($token, array('+', '-', '*', '/', '^', '>', '<', '='))) {