выберите имя, max (значение) из группы out_pumptable по имени
Хотя я не предлагаю использовать eval
для этого (это not решение), проблема в том, что eval
ожидает полные строки кода, а не только фрагменты.
$ma ="2+10";
$p = eval('return '.$ma.';');
print $p;
Должен делать то, что вы хотите.
Лучшим решением было бы написать токенизатор / парсер для вашего математического выражения. Вот простой пример, основанный на регулярном выражении, который дает вам пример:
$ma = "2+10";
if(preg_match('/(\d+)(?:\s*)([\+\-\*\/])(?:\s*)(\d+)/', $ma, $matches) !== FALSE){
$operator = $matches[2];
switch($operator){
case '+':
$p = $matches[1] + $matches[3];
break;
case '-':
$p = $matches[1] - $matches[3];
break;
case '*':
$p = $matches[1] * $matches[3];
break;
case '/':
$p = $matches[1] / $matches[3];
break;
}
echo $p;
}
Выражение eval'd должно заканчиваться на «;»
Попробуйте следующее:
$ma ="2+10;";
$p = eval($ma);
print $p;
Кстати, это выходит за рамки, но функция «eval» выиграла 't возвращает значение выражения. eval ('2 + 10') не вернется 12. Если вы хотите, чтобы он вернул 12, вы должны eval ('return 2 + 10;');
$p
пуста. добавьте echo
внутрь: $ma ="echo 2+10;";
– S.Thiongane
18 September 2013 в 20:45
Взгляните на это.
Я использую это в системе учета, где вы можете писать математические выражения в полях ввода количества.
$Cal = new Field_calculate();
$result = $Cal->calculate('5+7'); // 12
$result = $Cal->calculate('(5+9)*5'); // 70
$result = $Cal->calculate('(10.2+0.5*(2-0.4))*2+(2.1*4)'); // 30.4
class Field_calculate {
const PATTERN = '/(?:\-?\d+(?:\.?\d+)?[\+\-\*\/])+\-?\d+(?:\.?\d+)?/';
const PARENTHESIS_DEPTH = 10;
public function calculate($input){
if(strpos($input, '+') != null || strpos($input, '-') != null || strpos($input, '/') != null || strpos($input, '*') != null){
// Remove white spaces and invalid math chars
$input = str_replace(',', '.', $input);
$input = preg_replace('[^0-9\.\+\-\*\/\(\)]', '', $input);
// Calculate each of the parenthesis from the top
$i = 0;
while(strpos($input, '(') || strpos($input, ')')){
$input = preg_replace_callback('/\(([^\(\)]+)\)/', 'self::callback', $input);
$i++;
if($i > self::PARENTHESIS_DEPTH){
break;
}
}
// Calculate the result
if(preg_match(self::PATTERN, $input, $match)){
return $this->compute($match[0]);
}
// To handle the special case of expressions surrounded by global parenthesis like "(1+1)"
if(is_numeric($input)){
return $input;
}
return 0;
}
return $input;
}
private function compute($input){
$compute = create_function('', 'return '.$input.';');
return 0 + $compute();
}
private function callback($input){
if(is_numeric($input[1])){
return $input[1];
}
elseif(preg_match(self::PATTERN, $input[1], $match)){
return $this->compute($match[0]);
}
return 0;
}
}
Использование функции eval очень опасно, если вы не можете управлять строковым аргументом.
Попробуйте Matex для безопасного вычисления математических формул.
Решено!
<?php
function evalmath($equation)
{
$result = 0;
// sanitize imput
$equation = preg_replace("/[^a-z0-9+\-.*\/()%]/","",$equation);
// convert alphabet to $variabel
$equation = preg_replace("/([a-z])+/i", "\$$0", $equation);
// convert percentages to decimal
$equation = preg_replace("/([+-])([0-9]{1})(%)/","*(1\$1.0\$2)",$equation);
$equation = preg_replace("/([+-])([0-9]+)(%)/","*(1\$1.\$2)",$equation);
$equation = preg_replace("/([0-9]{1})(%)/",".0\$1",$equation);
$equation = preg_replace("/([0-9]+)(%)/",".\$1",$equation);
if ( $equation != "" ){
$result = @eval("return " . $equation . ";" );
}
if ($result == null) {
throw new Exception("Unable to calculate equation");
}
echo $result;
// return $equation;
}
$a = 2;
$b = 3;
$c = 5;
$f1 = "a*b+c";
$f1 = str_replace("a", $a, $f1);
$f1 = str_replace("b", $b, $f1);
$f1 = str_replace("c", $c, $f1);
evalmath($f1);
/*if ( $equation != "" ){
$result = @eval("return " . $equation . ";" );
}
if ($result == null) {
throw new Exception("Unable to calculate equation");
}
echo $result;*/
?>
eval
Оценивает данный код как PHP
. Это означает, что он выполнит данный параметр как часть кода PHP.
Чтобы исправить ваш код, используйте это:
$ma ="print (2+10);";
eval($ma);
str_replace
вокруг$matches[1]
и$matches[3]
или аналогичного), это будет полностью зависеть от вашего использования - это сработало для моих нужд./([\d\.\s]+)([\+\-\*\/])([\d\.\s]+)/
– Warren Sergent 3 February 2016 в 07:28/([\d\.\s]+)([\+\-\*\/])(\-?[\d\.\s]+)/
позволит второму числу быть отрицательным значением (например, в случае 24,5 * -4). Это сломалось бы, так как вторая группа не нашла бы отрицательного числа. – Warren Sergent 3 February 2016 в 07:44100+01
? Я использую функцию eval, но я немного смущен тем, как писать регулярное выражение для проверки чисел, таких как011,090,001 etc etc
– halapgos1 4 October 2016 в 20:44