How to convert and run a formula in PHP?

Asked

Viewed 44 times

1

Hello, I need to run a formula that is string. This formula comes from an attribute in the BD table. Example: formula = "{{C1}} - {{C2}}"

I get the string from the database in the format above. I replace C1 and C2 by numbers in this way:

$a1 = 2;
$a2 = 1;
$formula = "{{c1}} - {{c2}}";
$f = str_replace("{{c1}}",$a1,$formula);
$f = str_replace("{{c2}}", $a2, $f);

print($f); // resultado = "2 - 1"

I need to run this calculation. Expected result in execution: 1. How to do?

  • That reminds me Eval is either good or bad?

  • If not with eval, you will probably have to create your own "formula compiler" with regex. It is not very recommended to use eval if you don’t know what you’re doing.

  • The formula always comes with the same sign?

  • The formula can contain the 4 operations at once. It can have complex formulas.

  • Ever tried to use a lib that has this? Example

  • I will implement the suggested lib and return if successful. thanks for while.

  • Has that one also, just have to make sure it’s not the bazuka to kill ant

  • Wallace Maxies, the Formulaparser worked very well. I did some tests and is ok. I could add as an answer to other colleagues?

  • Look at that answer here:

  • Please avoid long discussions in the comments; your talk was moved to the chat

Show 5 more comments

1 answer

2

To process a string in PHP and turn it into a "real" result, you may need to walk a path, let’s say, complicated...

Eval, one possibility, but I’d rule it out...

First, it is likely that the easiest way [in terms of "code size"] to execute this code would be using the infamous eval.

Example:

$a1 = 2;
$a2 = 1;
$formula = "{{c1}} - {{c2}}";

$codigo = strtr($formula, [
   '{{c1}}' => $a1,
   '{{c2}}' => $a2,
]);

$resultado = eval(sprintf('return %s;', $codigo));

An important observation that needs to be made (and I will put in bold inclusive), is that You should avoid using eval as much as possible, unless you know what you’re doing.

That answer of Maniero here on the site shows well the care that should be taken.

Parse

Another way is you write a function that will parse your string to interpret its formula and return a result. It is not an easy task because you will have to write a function/class that interprets your string and performs complex operations.

In my case, I made an example, but it’s very simple:

function formula_parser($formula)
{
    $parts = array_map('trim', preg_split('/(\d+)/', $formula, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY));

    $total = 0;
    $operator = '+';

    foreach ($parts as $key => $part) {
        
        if (! is_numeric($part)) {
            $operator = $part;
            continue;
        }

        switch ($operator) {
            case '+':
                $total += $part;
                break;
            case '-':
                $total -= $part;
                break;
            case '*':
                $total *= $part;
                break;
            case '/':
                $total /= $part;
                break;
        }
    }

    return $total;
}

Results:

$formulas = [
    '1 + 3 + 4',
    '3 - 5 + 4',
    '3 * 5 * 10',
    '10 * 10 / 5'
];

foreach ($formulas as $formula) {
    var_dump(formula_parser($formula));
}

// int(8)
// int(2)
// int(150)
// int(20)

It is obvious that the above function is just a small demonstration, but note the amount of things that needed to be done to do simple mathematical operations (this example function does not even support float, including).

Biliotec

Perhaps the most viable option. There are some libraries that have parser written to make your life easier.

I remember the Symfony Language Expression and the Formulate Parser.

If you look at the source code of any of them, you will notice that writing a "formula parser" is not such a simple thing, but perhaps one of these tips can help.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.