Мне нужно создать приложение, которое вычисляет некоторые данные. Я не знаю, какие вычисления могут потребовать ученые.Как оценивать арифметические вычисления?
Например, Пользователь A будет необходимо вычислить (А + 5) * 3 пользователя Б захочет, чтобы вычислить (А + 14) ² * пи
арифметики формула определяется учеными и хранится в базы данных от администратора.
Простой способ это сделать:
<?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);
Но Eval зло, как это объясняется @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-функции, библиотеки pearl или PECL, чтобы помочь мне? функция arithmetic_eval
?
(я не прошу в Security.SE, потому что мой вопрос касается только PHP)