Parse math operations with PHP
Asked Answered
H

7

5

I am working on a project where I need to make a function that will parse the 4 default math operations (addition, subtraction, multiplication, division). It would be nice if the function could parse operations between brackets.

So, a must is that the function first check for multiplication and division operations (should check for that after it parser all operations between brackets if they exist, and that rule should apply for bracket operations [the biggest problem is that the brackets can contain brackets]). After doing all multiplication and division operations, it should do all addition and subtraction operations. The final number should be returned by functions.

Another nice addition would be a RegExp string that will check for math operations.

Thanks in advance!

Hydrophobia answered 27/4, 2011 at 11:56 Comment(6)
For your parenthesis problem : you should learn recursion to learn recursionMicrospore
The 'question' starts out with "I am working on a project" but quickly becomes a wish-list of features.Charactery
Sounds like a homework problem to me. Is this a homework problem?Kurtis
maybe math parser will help #1015742Julieannjulien
@Fivell: Why don't you submit that as an answer?Sporogenesis
@Sander Marechal: did itJulieannjulien
O
6

This should be pretty secure:

function do_maths($expression) {
  eval('$o = ' . preg_replace('/[^0-9\+\-\*\/\(\)\.]/', '', $expression) . ';');
  return $o;
}

echo do_maths('1+1');
Omland answered 27/4, 2011 at 14:31 Comment(1)
what should i have to change if i have to support floating numbers too?/Eichmann
C
2

You could use eval() (WARNING: be sure what enters is a math operation and not some other arbitrary input or php code).

$input = "3 + (4 - 2 * 8) / 2";

eval('$result = ' . $input . ';');

echo "The result is $result";
Candlewood answered 27/4, 2011 at 14:18 Comment(2)
I wonder if it would be possible to make an eval() 100% safe for math expressions if you were to check for any unrecognized character; i.e. preg_replace('~[^0-9.()-+*/]~', '', $input);Mingmingche
@Mingmingche probably that would work, and is the method used in the accepted answer as well.Crissie
J
2

there was a similar problem
How to evaluate formula passed as string in PHP? you can try to use Class: Eval Math from php classes http://www.phpclasses.org/package/2695-PHP-Safely-evaluate-mathematical-expressions.html

Julieannjulien answered 27/4, 2011 at 14:34 Comment(1)
Link-only answerAilurophile
C
2

I can recommend https://github.com/andig/php-shunting-yard which is a PSR-0 compatible implementation of the Shunting Yard algorithm.

Comparable answered 17/1, 2014 at 7:33 Comment(1)
Thanks for this amazing suggestion, being able to define custom functions is super useful.Fancywork
R
0

Regular expressions aren't the answer here; I suggest using an expression tree where all terminal nodes are constants or variables, and the rest of the nodes are operators. For example, 2 + 3 * 4 becomes:

+ --- 2
  |
  --- * --- 3
        |
        --- 4

Then, you evaluate the expression by using a depth-first traversal. In PHP it's sort of difficult to represent trees, but you could either use a built-in library as a commenter suggested or represent them using an associative array of arrays.

Raeleneraf answered 27/4, 2011 at 14:29 Comment(0)
S
0

if you want a truly safe math parser, then eval won't do it. bcParserPHP can do it. It is implemented in PHP and does not use eval, thus it is very secure.

Stagner answered 21/7, 2011 at 16:22 Comment(0)
E
-1

If the input does not include unary operators you can try this library I recently created: https://github.com/anastasd/expression-parser

Here is an example how to parse arithmetic expressions. The input does not need to be very well formatted:

$settings = new Settings(Settings::PHP);
$parser = new Parser($settings);
$input = ' ($a- 2.7182)* (3.1416+$b) / $c';

$output = $parser->parse($input, ['$a', '$b', '$c'])
  ->prepare()
  ->evaluate([1, 2, 3]);

// $output is -2.9447657066667

Instead of evaluating the input with numbers you can "compile" it in a function that can be saved in a file.

$settings = new Settings(Settings::PHP);
$parser = new Parser($settings);
$input = ' ($a- 2.7182)* (3.1416+$b) / $c';

$output = $parser->parse($input, ['$a', '$b', '$c'])
    ->prepare()
    ->compile(["compress"]);

// $output is 'function expressionResult( $a,$b,$c ){ return ($a-2.7182)*(3.1416+$b)/$c ;}'

You can easily create your own parser with just the four arithmetic operators. Please have a look at the examples with a custom parser.

Echoechoic answered 5/10 at 22:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.