php math eval

php - calcular la expresión matemática de una cadena usando eval



math (7)

Mira esto..

Lo uso en un sistema de contabilidad donde puedes escribir expresiones matemáticas en los campos de entrada de cantidades.

Ejemplos

$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

Código

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; } }

Quiero calcular la expresión matemática de una cadena. He leído que la solución a esto es usar eval (). Pero cuando intento ejecutar el siguiente código:

<?php $ma ="2+10"; $p = eval($ma); print $p; ?>

Me da el siguiente error:

Error de análisis: error de sintaxis, final inesperado en C: / xampp / htdocs / eclipseWorkspaceWebDev / MandatoryHandinSite / tester.php (4): eval () ''d código en la línea 1

¿Alguien sabe la solución a este problema?


Recientemente he creado un paquete PHP que proporciona una función de ayuda math_eval . Hace exactamente lo que necesita, sin la necesidad de utilizar la función eval potencialmente insegura.

Simplemente pasa la versión de la cadena de la expresión matemática y devuelve el resultado.

$two = math_eval(''1 + 1''); $three = math_eval(''5 - 2''); $ten = math_eval(''2 * 5''); $four = math_eval(''8 / 2'');

También puede pasar variables, que serán sustituidas si es necesario.

$ten = math_eval(''a + b'', [''a'' => 7, ''b'' => 3]); $fifteen = math_eval(''x * y'', [''x'' => 3, ''y'' => 5]);

Enlace: https://github.com/langleyfoxall/math_eval


Resuelto

<?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;*/ ?>


Si bien no sugiero usar eval para esto (no es la solución), el problema es que eval espera líneas completas de código, no solo fragmentos.

$ma ="2+10"; $p = eval(''return ''.$ma.'';''); print $p;

Debes hacer lo que quieras.

Una mejor solución sería escribir un tokenizer / parser para tu expresión matemática. Aquí hay una muy simple basada en expresiones regulares para darle un ejemplo:

$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; }


Una expresión de evaluación debe terminar con ";"

Prueba esto :

$ma ="2+10;"; $p = eval($ma); print $p;

Por cierto, esto está fuera del alcance, pero la función ''eval'' no devolverá el valor de la expresión. eval (''2 + 10'') no devolverá 12. Si desea que devuelva 12, debe evaluar (''return 2 + 10;'');


Usar la función eval es muy peligroso cuando no puedes controlar el argumento de la cadena.

Pruebe Matex para el cálculo seguro de fórmulas matemáticas.


eval evalúa el código dado como PHP . Lo que significa que ejecutará el parámetro dado como un fragmento de código PHP.

Para corregir su código, use esto:

$ma ="print (2+10);"; eval($ma);