我想知道是否有一种安全的方法来评估数学,比如
2+2
10000+12000
10000-20
2 + 2
40 - 20 + 23 - 12
而不必使用eval()
,因为输入可以来自任何用户。我需要实现的只是整数的加法和减法。
有没有已经存在的代码片段,或者我没有遇到过的PHP函数?
考虑到PHP中可用的各种数学函数,我会质疑使用eval
。你说过你只想做简单的数学运算——使用eval
的唯一原因是执行更复杂的运算,或者从用户那里接受整个等式。
如果你只想加或减,用intval
净化输入,然后去城里:
$number1 = '100';
$number2 = 'shell_exec(''rm -rf *'')';
echo intval($number1) + intval($number2); // 100
试试看:http://codepad.org/LSUDUw1M
这是因为intval
忽略任何非数字的内容。
如果您确实从用户输入(即100 - 20
)中获得了整个等式,则可以使用preg_replace
删除除允许的运算符和数字之外的任何内容:
$input = '20 + 4; shell_exec(''rm *'')';
$input = preg_replace(
'/[^0-9+-]/',
'',
$input
);
eval('$result = '.$input.';');
echo 'result: '.$result; // 24
试试看:http://codepad.org/tnISDPJ3
在这里,我们使用正则表达式/[^0-9+-]/
,它匹配任何NOT 0-9 OR+OR-,并用空字符串替换它。
如果你想通过允许的方程获得更多的深度,请直接从eval
手册页面获取:
// credit for code to bohwaz (http://www.php.net/manual/en/function.eval.php#107377)
$test = '2+3*pi';
// Remove whitespaces
$test = preg_replace('/'s+/', '', $test);
$number = '(?:'d+(?:[,.]'d+)?|pi|π)'; // What is a number
$functions = '(?:abs|a?cosh?|a?sinh?|a?tanh?|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;
}
文档
preg_replace
-http://php.net/manual/en/function.preg-replace.phpintval
-http://php.net/manual/en/function.intval.phpeval
-http://php.net/manual/en/function.eval.php- PHP数学函数-http://www.php.net/manual/en/ref.math.php
您可以自己解析表达式。
类似这样的东西:
// Minus is the same as plus a negative
// Also remove spaces after minus signs
$str = preg_replace('/-'s*('d+)/', '+-$1', $str);
// Split on plusses
$nums = explode('+', $str);
// Trim values
$nums = array_map('trim', $nums);
// Add 'em up
echo array_sum($nums);
演示:http://codepad.org/ANc0gh27
我在计算器脚本中使用了这个方法。
$field1 = $_GET["field1"];
$field2 = $_GET["field2"];
$answer = $field1 + $field2;
echo "$field1 + $field2 = $answer";