Надежно оценить простые математические данные

Я хотел бы знать, был ли безопасный способ оценить математику, как

2+2 10000+12000 10000-20 2 + 2 40 - 20 + 23 - 12 

Без использования eval() поскольку входные данные могут поступать от любых пользователей. То, что мне нужно реализовать, это только добавления и вычитания целых чисел.

Есть ли какие-либо фрагменты, которые уже существуют для этого, или любые функции PHP, с которыми я не сталкивался?

Я бы спросил, используя eval , учитывая разнообразие математических функций, доступных в PHP. Вы сказали, что хотите сделать просто математику – единственная причина использования 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; } 

Документация

Вы можете сами разобрать выражения.

Что-то вроде этого:

 // 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";