我会质疑使用eval
,考虑到 PHP 中可用的各种数学函数。你说过你只想做简单的数学——这是使用的唯一原因eval
是执行更复杂的操作,或者完全接受用户的方程。
如果您只想加或减,请使用以下命令清理输入intval
并进城:
$number1 = '100';
$number2 = 'shell_exec(\'rm -rf *\')';
echo intval($number1) + intval($number2); // 100
Try it: http://codepad.org/LSUDUw1M 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
Try it: http://codepad.org/tnISDPJ3 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.php http://php.net/manual/en/function.preg-replace.php
-
intval
- http://php.net/manual/en/function.intval.php http://php.net/manual/en/function.intval.php
-
eval
- http://php.net/manual/en/function.eval.php http://php.net/manual/en/function.eval.php
- PHP 数学函数 -http://www.php.net/manual/en/ref.math.php http://www.php.net/manual/en/ref.math.php