我必须建立一个计算一些数据的应用程序。我不知道科学家可以问什么计算。如何评估算术计算?
例如, 用户A将要计算(A + 5)* 3 用户B将要计算(A + 14)²* PI
的算术公式由科学家定义并存储在数据库由管理员。
最简单的方法就是做:
<?php
//Formula is initialized by a query in database
$formula= '(A + 3) * 5';
//$ value is an integer entered by UserA and verify by Controller
$value = 42;
$arithmetic = str_replace('A', $formula, $value);
$result = eval($arithmetic);
但因为它是由@thpl在此answer
解释评估和演示是邪恶的,我有两个选择:
- 要做好很多分析和转换公式的每个字符和 创建一个很好的计算类。 (发现 一个
+
和替换+
字符的每个侧面的操作通过调用addition
法等 等 - 检查
$formula
具有良好的(是否安全?)正则表达式,并调用邪恶eval
功能。
第一个解决方案似乎更安全,但很长的发展
对于第二个方案,我发现这对PHP文档:
<?php
$test = '2+3*pi';
// Remove whitespaces
$test = preg_replace('/\s+/', '', $test);
$number = '(?:\d+(?:[,.]\d+)?|pi|π)'; // What is a number
$functions = '(?:sinh?|cosh?|tanh?|abs|acosh?|asinh?|atanh?|exp|log10|deg2rad|rad2deg|sqrt|ceil|floor|round)'; // Allowed PHP functions
$operators = '[+\/*\^%-]'; // Allowed math operators
$regexp = '/^((' . $number . '|' . $functions . '\s*\((?1)+\)|\((?1)+\))(?:' . $operators . '(?2))?)+$/'; // Final regexp, heavily using recursive patterns
if (preg_match($regexp, $q)) {
$test = preg_replace('!pi|π!', 'pi()', $test); // Replace pi with pi function
eval('$result = ' . $test . ';');
} else {
$result = false;
}
第一个问题:第二个解决方案是否足够安全?
我在互联网上搜索(当然),但找到的最好的解决方案是以前的代码。有一些PHP函数,珍珠或PECL库来帮助我吗?一个arithmetic_eval
函数?
(我不Security.SE问,因为我的问题只涉及PHP)