我得到了一个包含要替换为整数并计算的特定字符的公式字符串。该公式来自不同的用户,整数值来自数据库。
示例:
$formula = 'x/100';
$formula = '(5*(x+20))';
...
我得到一个个人数字,比如说34,并将其用作公式中的x。
我该如何使用PHP?找不到解决方案。
我尝试使用用户功能,但不幸的是,这似乎不起作用。
$number = 34;
$formula = str_replace('x', $number, $formula);
$result = function () use ($formula) {
echo round($formula);
};
echo $example();
结果为“ 34”,而不是“ 34/100”。
答案 0 :(得分:1)
处理用户编写的纯文本公式需要大量工作,以解析给定的表达式,标记化,验证并最终通过根据需要替换占位符来执行。 (在这种情况下,x
是一个占位符。)
从编程的角度来看,这种目标非常适合进入Abstract Syntax Trees和Lexical Analysis的世界。就个人而言,在尝试构建复杂的东西之前,我会先看一下doctrine/lexer。它可以减少您实现很多目标所需的总体工作。 Doctrine ORM使用 doctrine / lexer 来理解用户编写的DQL查询。
我不建议使用基于 str_replace , preg_replace 和 eval()的hacky解决方案,因为这可能会导致严重的安全问题。用户可以以论坛和开发人员的身份编写任何废话,您始终需要首先进行验证。如果没有用于理解给定公式结构的规则列表,则验证几乎是不可能的。
更新
为证明它的缺陷和危险,下面是一个相对安全的eval
方案。
下面的废话只是为了演示eval()的问题,而不是问题的实际解决方案。不要使用它!
$formula = '(12+5) * 2 / x';
/**
* Strip out everything other than a dot, arithmetic operators, paranthesis
* and the letter x to use as placeholder from given formula
*/
$filteredExpression = preg_replace('/[^\(\)\+\-\.\*\/\d+\.x]/', '', $formula);
$actualFormula = str_replace('x', 1, $filteredExpression);
$result = eval('return ' . $actualFormula . ';');
此示例部分可行,但仍然存在以下重要问题:
PHP解析错误:语法错误,意外的')'..
PHP警告:除以零英寸。
,
代替点.
作为十进制占位符。这可能会导致错误/意外的结果。**
)或递增/递减++
,--
运算符,这也可能最终导致错误/意外的结果。 (更复杂的正则表达式可能对此有所帮助,但不值得)SUM()
,AVG()
,MIN()
,MAX()
等。现在该怎么办?甚至其中一些是部分可实现的,完成这一工作的代码在此之后很快就会变得一团糟。