I want to calculate math expression from a string. I have read that the solution to this is to use eval(). But when I try to run the following code:

``````<?php

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

?>
``````

It gives me the following error:

Parse error: syntax error, unexpected \$end in C:\xampp\htdocs\eclipseWorkspaceWebDev\MandatoryHandinSite\tester.php(4) : eval()'d code on line 1

Does someone know the solution to this problem.

## Solution 1

While I don't suggest using `eval` for this (it is not the solution), the problem is that `eval` expects complete lines of code, not just fragments.

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

Should do what you want.

A better solution would be to write a tokenizer/parser for your math expression. Here's a very simple regex-based one to give you an example:

``````\$ma = "2+10";

if(preg_match('/(\d+)(?:\s*)([\+\-\*\/])(?:\s*)(\d+)/', \$ma, \$matches) !== FALSE){
\$operator = \$matches;

switch(\$operator){
case '+':
\$p = \$matches + \$matches;
break;
case '-':
\$p = \$matches - \$matches;
break;
case '*':
\$p = \$matches * \$matches;
break;
case '/':
\$p = \$matches / \$matches;
break;
}

echo \$p;
}
``````

## Solution 2

Take a look at this..

I use this in an accounting system where you can write math expressions in amount input fields..

# Examples

``````\$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
``````

# Code

``````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);
}
// 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)){
return \$input;
}
elseif(preg_match(self::PATTERN, \$input, \$match)){
return \$this->compute(\$match);
}

return 0;
}
}
``````

## Solution 3

I recently created a PHP package that provides a `math_eval` helper function. It does exactly what you need, without the need to use the potentially unsafe `eval` function.

You just pass in the string version of the mathematical expression and it returns the result.

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

You can also pass in variables, which will be substituted if needed.

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

## Solution 4

Using eval function is very dangerous when you can't control the string argument.

Try Matex for safe Mathematical formulas calculation.

## Solution 5

Solved!

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

## Solution 6

This method has two major drawbacks:

• Security, php script is being evaluated by the eval function. This is bad, especially when the user wants to inject malicious code.

• Complexity

I created this, check it out: Formula Interpreter

# How does it work ?

First, create an instance of `FormulaInterpreter` with the formula and its parameters

``````\$formulaInterpreter = new FormulaInterpreter("x + y", ["x" => 10, "y" => 20]);
``````

Use the `execute()` method to interpret the formula. It will return the result:

``````echo \$formulaInterpreter->execute();
``````

in a single line

``````echo (new FormulaInterpreter("x + y", ["x" => 10, "y" => 20]))->execute();
``````

# Examples

``````# Formula: speed = distance / time
\$speed = (new FormulaInterpreter("distance/time", ["distance" => 338, "time" => 5]))->execute() ;
echo \$speed;

#Venezuela night overtime (ordinary_work_day in hours): (normal_salary * days_in_a_work_month)/ordinary_work_day
\$parameters = ["normal_salary" => 21000, "days_in_a_work_month" => 30, "ordinary_work_day" => 8];
\$venezuelaLOTTTArt118NightOvertime = (new FormulaInterpreter("(normal_salary/days_in_a_work_month)/ordinary_work_day", \$parameters))->execute();
echo \$venezuelaLOTTTArt118NightOvertime;

#cicle area
echo \$cicleArea;

``````

# About the formulas

1. It must contain at least two operands and an operator.
2. Operands' name could be in upper or lower case.
3. By now, math functions as sin, cos, pow are not included. I'm working to include them.
4. If your formula is not valid, you will get an error message like: Error, your formula (single_variable) is not valid.
5. Parameters' values must be numeric.

# You can improve it if you want to!

## Solution 7

`eval` Evaluates the given code as `PHP`. Meaning that it will execute the given paremeter as a PHP piece of code.

To correct your code, use this :

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

## Solution 8

Using eval function

`````` protected function getStringArthmeticOperation(\$value, \$deduct)
{
if(\$value > 0){
\$operator = '-';
}else{
\$operator = '+';
}
\$mathStr = '\$value \$operator \$deduct';
eval("\\$mathStr = \"\$mathStr\";");
\$userAvailableUl = eval('return '.\$mathStr.';');
return \$userAvailableUl;
}

\$this->getStringArthmeticOperation(3, 1); //2
``````

## Solution 9

An eval'd expression should end with ";"

Try this :

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

By the way, this is out of scope but the 'eval' function won't return the value of the expression. eval('2+10') won't return 12. If you want it to return 12, you should eval('return 2+10;');